2009-02-20 65 views
23

可以說我有表之間「表1」和「表2」是由來自兩個int字段的簡單許多一對多表:「表1-ID」和「表2-ID」。我應該如何索引這個鏈接表?如何正確索引鏈接表在MySQL許多一對多連接?

我以前只是做一個複合主指數(表1-ID,表2-ID),但我看,如果你更改查詢中字段的順序該指數可能無法正常工作。那麼最佳解決方案是什麼 - 爲沒有主索引的每個領域制定獨立索引?

謝謝。

回答

25

這取決於你如何進行搜索。

如果搜索是這樣的:

/* Given a value from table1, find all related values from table2 */ 
SELECT * 
FROM table1 t1 
JOIN table_table tt ON (tt.table_1 = t1.id) 
JOIN table2 t2 ON (t2.id = tt.table_2) 
WHERE t1.id = @id 

,那麼你需要:

ALTER TABLE table_table ADD CONSTRAINT pk_table1_table2 (table_1, table_2) 

在這種情況下,table1將領先NESTED LOOPS,只有當table1是第一個索引的索引將是可用。

如果搜索是這樣的:

/* Given a value from table2, find all related values from table1 */ 
SELECT * 
FROM table2 t2 
JOIN table_table tt ON (tt.table_2 = t2.id) 
JOIN table1 t1 ON (t1.id = tt.table_1) 
WHERE t2.id = @id 

,那麼你需要:

ALTER TABLE table_table ADD CONSTRAINT pk_table1_table2 (table_2, table_1) 

上述原因。

這裏你不需要獨立的索引。可以在任何可以使用第一列的普通索引的地方使用組合索引。如果使用獨立的索引,你將不能爲這兩個值有效地搜索:

/* Check if relationship exists between two given values */ 
SELECT 1 
FROM table_table 
WHERE table_1 = @id1 
    AND table_2 = @id2 

對於這樣的查詢,則需要在兩列的至少一個指引。

這是從來沒有壞到有第二場附加指標:

ALTER TABLE table_table ADD CONSTRAINT pk_table1_table2 PRIMARY KEY (table_1, table_2) 
CREATE INDEX ix_table2 ON table_table (table_2) 

主鍵將被用於搜索on both values和基於的table_1值的搜索,更多的索引將被用於基於搜索值爲table_2

+0

感謝您的詳細解答,但如果我搜索兩種方式呢?另外我使用Hibernate,所以我甚至不確定它使用的是哪種方式。 – serg 2009-02-20 22:02:49

+2

如果您搜索兩種方式,您需要兩個索引:PRIMARY KEY的一個組合和PRIMARY KEY中第二個的列的一個平鋪。它在我的帖子底部。 – Quassnoi 2009-02-20 22:05:09

4

只要您在查詢中指定了這兩個鍵,則它們在查詢中的順序無關緊要,也不重要在索引中指定它們的順序。

但是,您有時只有一個或另一個密鑰不是不可能的。如果您有時只ID_1,那麼這應該是第一(但你仍然只需要一個索引)。

如果您有時有一個,有時是另一個,有時兩個,您需要一個索引與兩個鍵,第二個(非唯一)索引與一個字段 - 更有選擇性的兩個鍵 - 和主要組合索引應以另一個鍵開始。

0

@Quassnoi,在您的第一個查詢中,您實際上只使用了tt.table_1鍵,正如我們從WHERE子句中看到的那樣:WHERE t1.id = @id。並在第二個查詢 - 只有tt.table_2

因此,由於WHERE table_1 = @id1 AND table_2 = @id2,多列索引可能僅適用於第三個查詢。如果這種查詢不會被使用,那麼您認爲應該使用兩個單獨的一列索引嗎?