2013-06-29 26 views
3

还有就是,在传统产品我支持,一个PHP查询到MySQL其作品有时并在其他时间挂起(也许是有限的,但如果是这样的不合理长的时间)。我的SQL技能相当有限,但我能够在mysql上手动运行查询,这是我迄今发现的。为什么查询有时挂而不是其他

鉴于表的订单“,“了LineItem”和“lineItemDefns”,

,其中每个顺序是一个对多了LineItem和 了LineItem是一到一个与lineItemDefinitions

和表每个报告(reportId)映射到一组订单OrderReports及其LINEITEM数据和下面的SQL查询:(这是从查询字符串倾倒立即调用DBI GETALL在PHP之前)

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); 

当我运行它本身返回几乎瞬间与单排第二选择。当我运行第一个select代替第二个select的orderId时,它会在不到一秒钟的时间内返回一个NULL estimatedTotalDuration。此reportId只有两行,它对应于此订单的两个lineItem行。 lineItems(inlineItemDefns)的estimatedDuration都是NULL。

所有查询的ID,主要和国外,都编入索引。

所有数字是整数,持续时间是以秒为单位(INT(11))。在这种情况下,itemCounts是1.

但是,当我像上面那样运行它时,它在我的测试数据库中工作(在30秒慢),但当它离开时间不合理(50分钟以上)以获取生产数据的等效报告。

没有空桌,好像被关起来的,而该报告是挂我可以运行前两个部分查询测试。

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

任何有关重写查询的建议都将被赞赏。

在Fedora 7的MySQL 5.0.37(测试数据库是在Fedora 8的MySQL 5.0.45)

一样,一分钱的大爆炸理论,这是我所知道的。哦,Fig Newton以马萨诸塞州牛顿命名。 ;)

回答

1

问题是,旧版本的MySQL没有优化in与子查询很好。特别是,它为每个可能的输出行运行子查询。 。 。一遍又一遍地做着select distinct

您可以将此子查询移到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联接语法。

+0

...但没有标准格式:)。+1无论如何 – Bohemian

+0

谢谢,戈登,我会尽快玩(尽快理解它 - SQL对我来说从来没有直觉过!) – Ilane

+0

您的意思是最后的“on orders.id = orep.orderId”线? – Ilane

相关问题