2013-06-29 28 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

相關問題