mysql-冗餘和重複索引

  mysql容許在相同列上建立多個索引,不管是有意仍是無心,mysql須要單獨維護重複的索引,而且優化器在優化查詢的時候也須要逐個地進行考慮,這會影響性能。mysql

  重複索引是指的在相同的列上按照相同的順序建立的相同類型的索引,應該避免這樣建立重複索引,發現之後也應該當即刪除。但,在相同的列上建立不一樣類型的索引來知足不一樣的查詢需求是能夠的。sql

CREATE TABLE test( ID INT NOT NULL PRIMARY KEY, A INT NOT NULL, B INT NOT NULL, UNIQUE(ID), INDEX(ID), ) ENGINE=InnoDB;

  這段SQL建立了3個重複索引。一般並無理由這麼作。服務器

  冗餘索引和重複索引有一些不一樣,若是建立了索引(a,b),再建立索引(a)就是冗餘索引,由於這只是前面一個索引的前綴索引,所以(a,b)也能夠看成(a)來使用,可是(b,a)就不是冗餘索引,索引(b)也不是,由於b不是索引(a,b)的最左前綴列,另外,其餘不一樣類型的索引在相同列上建立(如哈希索引和全文索引)不會是B-Tree索引的冗餘索引,而不管覆蓋的索引列是什麼。工具

  冗餘索引一般發生再爲表添加新索引的時候。例如,有人可能會增長一個新的索引(A,B)而不是擴展之後的索引(A)。還有一種狀況是將一個索引擴展爲(A,ID),其中ID是主鍵,對於InnoDB來講主鍵已經包含在二級索引中了,因此這也是冗餘的。性能

  大多數狀況下都不須要冗餘索引,應該儘可能擴展已有的索引而不是建立新索引,但也有時候處於性能方面的考慮須要冗餘索引,由於擴展已有的索引會致使其變得太大,從而影響其餘使用該索引的查詢性能。如:若是在整數列上有一個索引,如今須要額外增長一個很長的varchar列來擴展該索引,那麼性可能會急劇降低,特別是有查詢把這個索引看成覆蓋索引,或者這是myisam表而且有不少範圍查詢的時候(因爲myisam的前綴壓縮)優化

  好比,有一張userinfo表。這個表有1000000條數據,對每一個state_id值大概有20000條記錄。在state_id有一個索引,那麼下面的SQL咱們稱之爲Q1spa

SELECT count(*) FROM userinfo WHERE state_id=5; --Q1

  改查詢的執行速度大概是每秒115次(QPS)code

  還有一個SQL,咱們稱之爲Q2blog

SELECT state_id,city,address FROM userinfo WHERE state_id=5; --Q2

  這個查詢的QPS是10,提高該索引性能最簡單的辦法就是狂戰索引爲(state_id,city,address),讓索引能覆蓋查詢:索引

ALERT TABLE userinfo ADD KEY state_id_2(state_id,city,address);

  (注:state_id已經有索引了,根據前面的概念,這是一個冗餘索引而不是重複索引)

怎麼找出冗餘索引和重複索引呢?

1.可使用Shlomi Noach的common_schema中的一些試圖來定位,common_schema是一系列能夠安裝到服務器上的經常使用的存儲和試圖。

2.可使用Percona Toolkit中的pt_duplicate-key-checker,該工具經過分析表結構來找出冗餘和重複的索引。

 

參考文獻:

 [1] Baron Schwartz等 著,寧海元等 譯 ;《高性能MySQL》(第3版); 電子工業出版社 ,2013

相關文章
相關標籤/搜索