Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 为什么查询有时挂起,而其他的却不挂起_Mysql - Fatal编程技术网

Mysql 为什么查询有时挂起,而其他的却不挂起

Mysql 为什么查询有时挂起,而其他的却不挂起,mysql,Mysql,在我支持的一个遗留产品中,对mysql的PHP查询有时有效,有时挂起可能是有限的,但如果是这样的话,持续时间就太长了。我的SQL技能非常有限,但我能够在mysql上手动运行查询,以下是我目前发现的情况 给定“订单”、“lineItems”和“lineItemDefns”表 其中,每个订单是一对多行项目和 lineItems与lineItemDefinitions是一对一的 和表OrderReports,它将每个报表reportId映射到一组订单及其行项目数据和以下SQl查询: SELECT SE

在我支持的一个遗留产品中,对mysql的PHP查询有时有效,有时挂起可能是有限的,但如果是这样的话,持续时间就太长了。我的SQL技能非常有限,但我能够在mysql上手动运行查询,以下是我目前发现的情况

给定“订单”、“lineItems”和“lineItemDefns”表

其中,每个订单是一对多行项目和 lineItems与lineItemDefinitions是一对一的

和表OrderReports,它将每个报表reportId映射到一组订单及其行项目数据和以下SQl查询:

SELECT SEC_TO_TIME(SUM(orders.itemCount*lineItems.itemCount*lineItemDefns.estimatedDuration)) as estimatedTotalDuration
FROM orders, lineItems, lineItemDefns
WHERE orders.id=lineItems.parentOrder
  AND lineItemDefns.id=lineItems.definitionId
  AND orders.id in 
      (SELECT DISTINCT orderId 
       FROM OrderReports
       WHERE OrderReports.reportId=98619);
这是在PHP中调用DBI getAll之前从查询字符串中转储的

当我单独运行第二个select时,它几乎立即返回一行。当我运行第一个select并用该orderId替换第二个select时,它在不到一秒钟的时间内返回一个空的estimatedTotalDuration。此reportId只有两行,对应于此订单的两行lineItem行。lineItemDefns中的lineItems的估计值均为NULL

查询中的所有ID(主ID和外部ID)都已编制索引

所有数字都是整数,持续时间以秒为单位int11。本例中的itemCounts为1

但是,当我像上面那样运行它时,它在我的测试数据库中以30秒的速度运行,但如果在50分钟以上的不合理的时间内运行,它将无法完成生产数据的等效报告

似乎没有表被锁定,因为我可以在挂起报表时运行前两个部分查询测试

是否有人能指出任何明显的原因,例如处理空估计值?。 同样,有没有关于下一步要看什么的提示?这是一个生产数据库,所以我不想做任何可能导致其他用户延迟的事情

如有任何修改查询的建议,我们将不胜感激

Fedora7上的mysql 5.0.37测试数据库是Fedora8上的mysql 5.0.45


就像大爆炸理论中的佩妮,这就是我所知道的。哦,牛顿是以牛顿的名字命名的

问题在于,MySQL的旧版本没有很好地优化子查询。特别是,它正在为每个可能的输出行运行子查询。一次又一次地进行选择

您可以将此子查询移动到from子句以解决此问题:

SELECT SEC_TO_TIME(SUM(orders.itemCount*lineItems.itemCount*lineItemDefns.estimatedDuration)) as estimatedTotalDuration
FROM orders join
     lineItems
     on orders.id=lineItems.parentOrder join
     lineItemDefns
     on lineItemDefns.id=lineItems.definitionId join
     (SELECT DISTINCT orderId 
      FROM OrderReports
      WHERE OrderReports.reportId=98619
     ) orep
     on orders.id = orep.id

我还将所有连接都移动到from子句中,以使用标准的ANSI连接语法。

谢谢,Gordon,我会尽快使用它,只要我理解它-SQL对我来说从来都不是直观的!你是指最后一行的orders.id=orep.orderId吗?哇-.34秒,比我的测试报告大两个数量级!非常感谢你,戈登!