2014-05-14 80 views
0

在僅包含物化查詢中的主鍵的臨時表上創建索引是否有什麼好處?在MySQL中只有一列索引表的性能

我想從特定表中刪除一些數據,以及其他具有外鍵引用的相關表。爲了提高性能,我將初始選擇物化成臨時表,然後加入它以便進行後續刪除。

臨時表只包含一列 - 子查詢中的主鍵。在臨時表的ID列上創建索引是否有任何性能優勢?在我的測試中,我看到了大約2%的改進(更多的是被索引創建的開銷所抵消),但是可能我可以測試的數據集還不夠大。

CREATE TEMPORARY TABLE ids AS (SELECT id FROM tableA WHERE xxx); 
DELETE tableB FROM tableB INNER JOIN ids ON tableB.a_id = ids.id; 
DELETE tableC FROM tableC INNER JOIN ids ON tableC.a_id = ids.id; 
... 
DELETE tableA FROM tableA INNER JOIN ids ON tableA.id = ids.id; 

由於來自IDS臨時表中的所有行將用於TableB中(A_ID被索引),以刪除行,是否有任何性能好處,以創建上的ID的臨時表中的主鍵/索引?有沒有更好的,完全不同的方法來解決這個問題?

+0

如果該列被聲明爲主鍵,那麼它已經有一個索引。 –

+0

沒錯。澄清 - 問題是添加該主鍵是否實際上會提高後續連接的性能。我會更新這個更清晰的。 – slikchucky

回答

1

它完全取決於您運行的查詢類型。如果您只運行需要讀取或返回整個表或整個表的重要子集的查詢,那麼添加索引只會導致寫性能下降(始終如此)。如果您經常執行可以使用這種索引的查詢來減少表中的磁盤頁I/O數(因爲您只查找一行或佔行很小的百分比),則添加索引將會顯着提高了這些查詢的性能。

+0

只是爲了確認 - 在我的具體情況下,臨時表中的所有行將在後續連接中使用(而不是一個小子集),因此將索引id列的優勢不在讓MySQL執行全表掃描? – slikchucky

+0

是的,如果在查詢處理過程中必須使用整個表,那麼索引不會有任何好處,事實上,如果數據庫查詢優化器正常工作,它將選擇忽略它,因爲使用索引會比完整的表掃描需要更多的I/O操作。 –

0

實際上,這是主鍵索引可能對性能造成危險的一種情況。

您基本上有兩個邏輯執行路徑的查詢。一種是讀取「其他」表並在ID中查找值。第二個是讀取id表並在「其他」表中查找值。後面的執行計劃是最好的,假設ID比另一個表小得多。

主鍵索引的問題在於它可能會混淆優化程序,通過真正使第一個選項看起來合理。如果您信任優化器,那麼擁有索引是沒有問題的。但它確實會增加混淆的可能性。

現在要進一步混淆事項,有些情況下索引會非常有益。當ids表相對於其他表很大時會發生這種情況 - 這些也很大。在這種情況下,您希望按照「其他」表的「主鍵」順序執行刪除操作。所以,按順序閱讀該表並查找該id是有道理的。只有當大多數頁面上至少有兩條要刪除的記錄時纔會出現這種情況。