2013-07-11 55 views
4

任何人可以幫助我在優化這個查詢,你會如何優化此MySQL查詢

SELECT(X1,  
    X2 
FROM TABLEAA 
WHERE 
     Y IN (SELECT Y FROM TABLEBB WHERE Z=SELECTED) 
    AND Y IN (SELECT Y FROM TABLECC WHERE ZZ=SELECTED)  
) 

何至於

TABLEAA : 1 million enteries  
TABLEBB : 22 million enteries  
TABLECC : 1.2 million enteries 

它的工作原理,但花費太多時間,差不多30秒

有沒有其他方法可以解決這個問題?

編輯:Z和ZZ是完全兩個不同的列

+1

當然,將其更改爲在列上使用連接和適當的索引會減少執行時間。 –

+0

任何人在沒有任何PK/FK的情況下如何創建或維護包含x百萬條目的表格? – wildplasser

+0

只是好奇,我們可以得到一篇關於運行時間改進了嗎? –

回答

2

添加一個索引Y我會用JOINs

SELECT DISTINCT 
    A.X1,  
    A.X2 
FROM TABLEAA A 
    JOIN TABLEBB B ON A.Y = B.Y AND B.Z='SELECTED' 
    JOIN TABLECC C ON A.Y = C.Y AND C.Z='SELECTED' 

此外,請確保您在A.Y,B.Y和C.Y上有適當的索引。您可以通過在您的Z列上添加索引來找到更好的性能 - 這取決於您的表格結構和其他幾個因素。

2

而不是使用子查詢,加入TABLEBB和TABLECC到TABLEAA,和你的WHERE子句中檢查ZZ = SLECTED,兩個連接的表。

確保參與外連接的列編入索引。

+0

優化器不會以相同的方式優化子查詢嗎? – zerkms

+0

不可以。沒有這個連接,它沒有機會這樣做。 –

+0

http://explainextended.com/2009/09/15/not-in-vs-not-exists-vs-left-join-is-null-sql-server/ ---它甚至可能在3年前,couldn是嗎? – zerkms

0

指數...

  • 添加一個索引來ZTABLEBB
  • 添加一個索引來ZZTABLECC
  • TABLEAA
+0

實際上對於'TABLEBB'來說,有一個複合'(Z,Y)'索引是個好主意。 'TABLECC'相同 – zerkms

+0

不確定這會有幫助,因爲它仍然需要掃描'Z = SLECTED'的每一行。但我可能是錯的。 –

+0

@D Stanley:如果你有'Z'索引 - DBMS首先找到行ID,然後取數據。如果索引中包含所有內容 - 它不需要執行數據查找(因爲它已經在索引中可用) – zerkms

0
SELECT X1, X2 FROM TABLEAA 
JOIN TABLEBB ON Y = Y JOIN TABLECC ON Y = Y 
WHERE TABLEBB.Z = SLECTED && TABLECC.ZZ = SLECTED