【老葉觀點】除了常見的建議外,還有幾個要點:html
7.一、超過20個長度的字符串列,最好建立前綴索引而非整列索引(例如:ALTER TABLE t1 ADD INDEX(user(20))),能夠有效提升索引利用率,不過它的缺點是對這個列排序時用不到前綴索引。前綴索引的長度能夠基於對該字段的統計得出,通常略大於平均長度一點就能夠了。mysql
7.二、按期用 pt-duplicate-key-checker 工具檢查並刪除重複的索引。好比 index idx1(a, b) 索引已經涵蓋了 index idx2(a),就能夠刪除 idx2 索引了。sql
7.三、有多字段聯合索引時,WHERE中過濾條件的字段順序無需和索引一致,但若是有排序、分組則就必須一致了。session
好比有聯合索引 idx1(a, b, c),那麼下面的SQL均可以完整用到索引:工具
SELECT ... WHERE b = ? AND c = ? AND a = ?; --注意到,WHERE中字段順序並無和索引字段順序一致 SELECT ... WHERE b = ? AND a = ? AND c = ?; SELECT ... WHERE a = ? AND b IN (?, ?) AND c = ?; SELECT ... WHERE a = ? AND b = ? ORDER BY c; SELECT ... WHERE a = ? AND b IN (?, ?) ORDER BY c; SELECT ... WHERE a = ? ORDER BY b, c; SELECT ... ORDER BY a, b, c; -- 可利用聯合索引完成排序
而下面幾個SQL則只能用到部分索引,或者可利用到ICP特性:優化
SELECT ... WHERE b = ? AND a = ?; -- 只能用到 (a, b) 部分 SELECT ... WHERE a IN (?, ?) AND b = ?; -- EXPLAIN顯示只用到 (a, b) 部分索引,同時有ICP SELECT ... WHERE (a BETWEEN ? AND ?) AND b = ?; -- EXPLAIN顯示只用到 (a, b) 部分索引,同時有ICP SELECT ... WHERE a = ? AND b IN (?, ?); -- EXPLAIN顯示只用到 (a, b) 部分索引,同時有ICP SELECT ... WHERE a = ? AND (b BETWEEN ? AND ?) AND c = ?; -- EXPLAIN顯示用到 (a, b, c) 整個索引,同時有ICP SELECT ... WHERE a = ? AND c = ?; -- EXPLAIN顯示只用到 (a) 部分索引,同時有ICP SELECT ... WHERE a = ? AND c >= ?; -- EXPLAIN顯示只用到 (a) 部分索引,同時有ICP ICP(index condition pushdown)是MySQL 5.6的新特性,其機制會讓索引的其餘部分也參與過濾,減小引擎層和server層之間的數據傳輸和回表請求,一般狀況下可大幅提高查詢效率。
下面的幾個SQL徹底用不到該索引:code
SELECT ... WHERE b = ?; SELECT ... WHERE b = ? AND c = ?; SELECT ... WHERE b = ? AND c = ?; SELECT ... ORDER BY b; SELECT ... ORDER BY b, a;
從上面的幾個例子就能看的出來,以往強調的WHERE條件字段順序要和索引順序一致才能使用索引的 「常識性誤導」 無需嚴格遵照。server
此外,有些時候查詢優化器指定的索引或執行計劃可能並非最優的,能夠手工指定最優索引,或者修改session級的 optimizer_switch 選項,關閉某些致使效果反而更差的特性(好比index merge一般是好事,但也遇到過用上index merge後反而更差的,這時候要麼強制指定其中一個索引,要麼能夠臨時關閉 index merge 特性)。htm