2014-05-13 71 views
0

請考慮下面的查詢MySql的複雜連接性能問題

SELECT * FROM PC_SMS_OUTBOUND_MESSAGE AS OM 
JOIN MM_TEXTOUT_SERVICE AS TOS ON TOS.TEXTOUT_SERVICE_ID = OM.SERVICE_ID 
JOIN PC_SERVICE_NUMBER AS SN ON OM.TO_SERVICE_NUMBER_ID = SN.SERVICE_NUMBER_ID  
JOIN PC_SUBSCRIBER AS SUB ON SUB.SERVICE_NUMBER_ID = SN.SERVICE_NUMBER_ID 
JOIN MM_CONTACT CON ON CON.SUBSCRIBER_ID = SUB.SUBSCRIBER_ID 

--AND CON.MM_CLIENT_ID = 1 

AND OM.CLIENT_ID= 1 
AND OM.CREATED>='2013-05-08 11:47:53' AND OM.CREATED<='2014-05-08 11:47:53' 
ORDER BY OM.SMS_OUTBOUND_MESSAGE_ID DESC LIMIT 50 

爲了得到我需要,我需要的過濾數據集(註釋)聯繫CLIENT_ID還有OUTBOUND_MESSAGES CLIENT_ID但是這是什麼樣的變化性能從毫秒到數十分鐘。

執行計劃沒有 「和CON.MM_CLIENT_ID = 1 」:

id select_type table type possible_keys key key_len ref rows filtered Extra 
1 SIMPLE OM index FK4E518EAA19F2EA2B,SERVICEID_IDX,CREATED_IDX,CLIENTID_IDX,CL_CR_ST_IDX,CL_CR_STYPE_ST_IDX,SID_TOSN_CL_CREATED_IDX PRIMARY 8 NULL 6741 3732.00 Using where 
1 SIMPLE SUB ref PRIMARY,FKA1845E3459A7AEF FKA1845E3459A7AEF 9 mmlive.OM.TO_SERVICE_NUMBER_ID 1 100.00 Using where 
1 SIMPLE SN eq_ref PRIMARY PRIMARY 8 mmlive.OM.TO_SERVICE_NUMBER_ID 1 100.00 Using where 
1 SIMPLE CON ref FK2BEC061CA525D30,SUB_CL_IDX FK2BEC061CA525D30 8 mmlive.SUB.SUBSCRIBER_ID 1 100.00 
1 SIMPLE TOS eq_ref PRIMARY,FKDB3DF298AB3EF4E2 PRIMARY 8 mmlive.OM.SERVICE_ID 1 100.00 

執行計劃與「 和CON.MM_CLIENT_ID = 1」:

id select_type table type possible_keys key key_len ref rows filtered Extra 
1 SIMPLE CON ref FK2BEC061CA525D30,FK2BEC06134399E2A,SUB_CL_IDX FK2BEC06134399E2A 8 const 18306 100.00 Using temporary; Using filesort 
1 SIMPLE SUB eq_ref PRIMARY,FKA1845E3459A7AEF PRIMARY 8 mmlive.CON.SUBSCRIBER_ID 1 100.00 
1 SIMPLE OM ref FK4E518EAA19F2EA2B,SERVICEID_IDX,CREATED_IDX,CLIENTID_IDX,CL_CR_ST_IDX,CL_CR_STYPE_ST_IDX,SID_TOSN_CL_CREATED_IDX FK4E518EAA19F2EA2B 9 mmlive.SUB.SERVICE_NUMBER_ID 3 100.00 Using where 
1 SIMPLE SN eq_ref PRIMARY PRIMARY 8 mmlive.SUB.SERVICE_NUMBER_ID 1 100.00 Using where 
1 SIMPLE TOS eq_ref PRIMARY,FKDB3DF298AB3EF4E2 PRIMARY 8 mmlive.OM.SERVICE_ID 1 100.00 

如何任何建議將上面的格式設置爲讓它在眼睛上更容易一點會很好。

ID字段是主鍵。 所有連接列上都有索引。

+0

你似乎缺少一個'WHERE'子句和'OM'表。這是我們需要查看EXPLAIN結果和包含表中所有索引的情況之一。 –

+0

我不認爲這裏需要什麼。並且當我測試時似乎沒有它工作正常。瞭解EXPLAIN結果。將不得不推出真正的查詢。 – dre

+0

被編輯以顯示具有執行計劃的真實查詢。 – dre

回答

0

我解決了謎題!無論如何,我的情況,所以我會分享。

這一切都歸結爲連接順序的變化,一旦我添加了額外的子句,您可以在執行計劃中清楚地看到它。當查詢速度很快時,出站消息位於計劃的頂部,但速度較慢時(添加子句後),聯繫人表位於頂部。 我認爲這意味着出站消息索引不能再用於導致可怕的排序;

"Using temporary; Using filesort" 

通過後直接選擇,我可以強制執行計劃通過查詢直接表示的順序進行連接簡單地增加STRAIGHT_JOIN關鍵字。 對於這個領域的更深入的知識的任何人都樂意與上面的任何事情發生衝突,但實際上發生了什麼,但它絕對奏效。

0

您可以通過使用一個子查詢來解決這個問題:

JOIN (SELECT C.* FROM CONTACTS C WHERE C.USER_ID = 1) ON C.SUBSCRIBER_ID = SUB.ID 

這將兌現匹配的行,這可能會對查詢計劃下游的影響。

如果這不起作用,然後編輯您的查詢,並添加:

  • explain計劃這兩個查詢。
  • 表中可用的索引。

編輯:

你可以嘗試創建一個綜合指數:

PC_SMS_OUTBOUND_MESSAGE(CLIENT_ID, CREATED, SERVICE_ID, TO_ SERVICE_ID, SMS_OUTBOUND_MESSAGE_ID); 

這可能會改變這兩個查詢計劃啓動對OM表具有適當的過濾,有望使結果穩定,好。

+0

曾嘗試過,沒有工作..我真的認爲它會! :(我猜這是因爲CONTACTS有數百萬條記錄,將會跟進更多的細節,說明將需要使用「真實世界」查詢。 – dre

+0

@dre ...。你有'CONTACTS(USER_ID)'索引嗎? –

+0

是的,我有那個索引 – dre