2013-10-23 33 views
0

[編輯]優化的MySQL自聯接查詢與不同的位置和順序

目標是使用自聯接基於序列字段(sequentialsortfield)以一定的順序中減去一個字段(someValue中)的值。查詢按原樣提供了正確的結果,但大數據集非常緩慢。使用mysql'explain'顯示這個查詢不是使用索引,而是使用filesort,儘管所有三個示例字段都被編入索引。如果我刪除'order by',它不再使用filesort [但是]不會根據所需的順序產生正確的結果。

我已經搜索和沒有看到SO或MySQL文檔已經幫助。在table1上似乎無法避免using filesort,除非我放棄order by但我確實需要它。指數存在於所有三個領域。

已經通過示例來說明我的問題。

結構 「表」:

id     INT 
somevalue    INT 
sequentialsortfield INT 

查詢:

select table1.somevalue-table2.somevalue as PrevRowDiff 
FROM table AS table1, 
table AS table2 
WHERE table1.sequentialsortfield+1 = table2.sequentialsortfield 
order by id; 
+1

我不確定你想要做什麼..你能更好地解釋自己嗎? – jcho360

+0

使用自連接以某種順序減去字段的值。查詢結果正確,但大數據集非常緩慢。使用mysql'explain'顯示這個查詢不是使用索引,而是使用filesort。如果我刪除'order by',它會進行優化,但不會根據所需的順序產生正確的結果。 – TransitDataHead

+0

有沒有附加條件?或者你要轉儲整個大型數據集? – newtover

回答

0

它實際上是相當棘手的,使這個查詢效率。長話短說,當你在sequentialsortfield(無論如何需要聯接有效)都有覆蓋索引時,你需要強制MySQL以主鍵順序輸出數據。

我會建議建立兩個綜合指數,並試圖暗中迫使他們中的一個:

說,

ALTER TABLE the_table ADD KEY the_one_to_force (id, sequentialsortfield, somevalue); 
ALTER TABLE the_table ADD KEY usual_one (sequentialsortfield, somevalue); 

和重寫查詢如下(你並不需要一個ORDER BY在這種情況下, ):

SELECT t1.somevalue-t2.somevalue as PrevRowDiff 
FROM the_table t1 FORCE INDEX (the_one_to_force) 
JOIN the_table t2 ON t1.sequentialsortfield+1 = t2.sequentialsortfield 

的想法是,該數據將在the_one_to_force指數和輸出數據的順序,如果有匹配被讀取(因爲它實際發生無論如何,但是合適的索引是由MySQL優化器根據查詢選擇的)。

+0

聽起來合乎邏輯我會盡快給你一個鏡頭並更新 - 謝謝! – TransitDataHead

+0

工作就像一個魅力!謝謝謝謝。 – TransitDataHead

0

試試這個:

Select table1.somevalue-table2.somevalue as PrevRowDiff 
FROM table AS table1 
Join table AS table2 
on table1.sequentialsortfield+1 = table2.sequentialsortfield 
group by sequentialsortfield 
order by id; 
+0

謝謝你的嘗試。這導致了「使用臨時;使用filesort」與原來的「使用filesort」。 – TransitDataHead