在我支持的旧产品中,有一个对 mysql 的 PHP 查询,它有时会工作,有时会挂起(可能是有限的,但如果是这样的话,持续时间会不合理)。我的 SQL 技能非常有限,但我能够在 mysql 上手动运行查询,这就是我目前所发现的。
给定表“orders”、“lineItems”和“lineItemDefns”,
其中每个订单是一对多的 lineItems 并且 lineItems 与 lineItemDefinitions 是一对一的
和表 OrderReports 将每个报告 (reportId) 映射到一组订单及其 lineItem 数据和以下 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 之前从查询字符串中转储的。)
当我自己运行第二个选择时,它几乎立即返回一行。当我运行第一个选择时,将该 orderId 替换为第二个选择,它会在不到一秒的时间内返回一个 NULL 的估计总持续时间。这个reportId只有两行,对应这个订单的两个lineItem行。lineItems(在 lineItemDefns 中)的estimatedDurations 都是NULL。
查询中的所有 id,主要的和外部的,都被索引。
所有数字都是整数,持续时间以秒为单位 (int(11))。本例中的 itemCounts 为 1。
但是,当我按上述方式运行它时,它可以在我的测试数据库中运行(在 30 秒时很慢),但是当离开不合理的时间(超过 50 分钟)以获得生产数据的等效报告时,它不会完成。
似乎没有表被锁定,因为我可以在报告挂起时运行前两个部分查询测试。
有人可以指出任何明显的原因(例如处理空的估计持续时间?)。同样,关于接下来要看什么的任何提示?这是一个生产数据库,所以我不想做任何可能导致其他用户延迟的事情。
任何重写查询的建议也将不胜感激。
Fedora 7 上的 mysql 5.0.37(测试数据库是 Fedora 8 上的 mysql 5.0.45)
就像,生活大爆炸中的佩妮,这就是我所知道的。哦,无花果牛顿是以马萨诸塞州牛顿命名的。;)