2011-08-31 193 views
12

我有一個MySQL數據庫如下表:多列索引VS多個索引

CREATE TABLE `secondary_images` (
    `imgId` int(10) unsigned NOT NULL AUTO_INCREMENT, 
    `primaryId` int(10) unsigned DEFAULT NULL, 
    `view` varchar(255) DEFAULT NULL, 
    `imgURL` varchar(255) DEFAULT NULL, 
    `imgDate` datetime DEFAULT NULL, 
    PRIMARY KEY (`imgId`), 
    KEY `primaryId` (`primaryId`), 
    KEY `imgDate` (`imgDate`) 
) ENGINE=MyISAM DEFAULT CHARSET=latin1 ; 

的SQL將是以下幾點:

SELECT imgURL, view FROM secondary_images 
WHERE primaryId={$imgId} ORDER BY imgDate DESC 

正如你可以看到我做了兩個primaryIdimgDate,索引鍵。我背後的想法是因爲WHERE子句的查詢結果使用primaryIdORDER子句使用imgDate

我的問題是,它會更好,因爲我現在使用多個索引?或者我應該多列索引(目前我不太瞭解的東西)?

這是我從得到解釋一下:

id = 1 
select_type = simple  
table = secondary_images   
type = ref 
possible_keys = primaryId 
key = primaryId 
key_len = 5 
ref = const 
rows = 1 
extra = Using where; Using filesort 

注:這不是使用多列索引,它是從使用上表中描述的結果。

+0

你可以發佈EXPLAIN的選擇? :) – Konerak

+2

請記住,indeces不是免費的。如果您有多個indeces,這意味着每次插入或更新時,都需要更新每個索引。您需要權衡這些更新的性能點擊與您在檢索時看到的性能改進。 – Marvo

+0

還請記住,如果您有許多行中具有相同值的列,則索引可能實際上會使性能變差。 – Poodlehat

回答

13

您應該使用上(primaryId,imgDate)多列索引,使MySQL是可以用它來選擇行和排序。

如果用於排序的所有列不是用於選擇的索引,MySQL使用「文件排序」戰略,即由排序的所有行(在內存中的,如果沒有太多的行;在磁盤上的其他人)。

如果用於排序的所有列索引,MySQL使用索引來獲取行的次序(有一些限制)。

MySQL爲索引使用樹結構。這允許直接訪問密鑰而不需要排序。

阿多列索引基本上是列連接的索引。這允許MySQL找到匹配primaryId={$imgId}的第一行,然後直接以正確的順序訪問所有其他行。

隨着primaryId單列索引,MySQL能夠找到匹配primaryId={$imgId}的所有行,但它會在沒有特定的順序找到行;所以它必須在那之後對它們進行排序。

EXPLAINORDER BY Optimization

+0

我不明白爲什麼 - 它將一列與另一列進行比較,而不是將兩列同時對另外兩列進行比較。你可以解釋嗎? – Poodlehat

+0

@ arnaud576875 - 非常感謝!你有什麼機會給我一個簡要的解釋,說明爲什麼在這種情況下這是最好的選擇?另外,我將如何使用'SQL'在'(primaryId,imgDate)'上使用多列索引來更改當前表? – stefmikhail

+0

@Poodlehat,stefmikhail我已經更新了答案 – arnaud576875

11

你解釋這個樣子的:

[id] => 1 
[select_type] => SIMPLE 
[table] => secondary_images 
[type] => ref 
[possible_keys] => primaryId 
[key] => primaryId 
[key_len] => 5 
[ref] => const 
[rows] => 1 
[Extra] => Using where; Using filesort 

讓我們看它。

[id] => 1 

表示我們正在討論第一張表。你只是在你的陳述中調用一張表。

[select_type] => SIMPLE 

我們正在做一個簡單的SELECT。

[table] => secondary_images 

有問題的表名。

[type] => ref 

選擇類型,對於連接最重要。

[possible_keys] => primaryId 

這是一個重要領域:它示出了密鑰可能被用於幫助查詢在執行速度更快。在這種情況下,只有您的主鍵被認爲是有用的。

[key] => primaryId 

這是一個重要領域:它示出了最後被用於哪個鍵(一個或多個)。在這種情況下,主鍵。

[key_len] => 5 
[ref] => const 
[rows] => 1 

猜測查詢檢查的行數。

[Extra] => Using where; Using filesort 

最重要的領域恕我直言。 - 使用where:您正在使用where語句。很好。 - 使用filesort:您的查詢結果如此之大,不能在內存中排序 。 MySQL必須將其寫入文件,對文件進行排序,然後輸出。這意味着磁盤訪問,並會放慢一切。 添加一個可以幫助排序的索引通常會有所幫助,但是解決 「使用filesort」本身就是一章。

+0

哇,哇哇。非常感謝你。這很容易理解。那麼,如何使用這些信息來決定是否需要多重索引鍵呢?我不會要求你進入filesort問題,因爲你自己說這完全是另一個問題,但是會切換到多索引鍵幫助嗎? – stefmikhail

+2

你應該首先**閱讀關於解釋。 MySQL網站是一個很好的開始,「高性能MySQL」是我讀過的最好的MySQL書籍。然後,瞭解它非常依賴於您的表,存儲引擎,配置(緩存大小等)以及表中的數據。因此,測試的最佳方式是:複製表格,並在副本上添加所需的索引。然後,比較說明。這就是爲什麼你需要理解解釋:) – Konerak

+0

再次感謝。非常感激。我會拿起那本書。 – stefmikhail