索引常用注意事项
索引
- 1. 索引怎么建好?
- 2. 索引容易失效的場景
- 3. 連接查詢索引優化
- 4. order by,group by
- 5. 覆蓋索引
- 6. 索引下推
1. 索引怎么建好?
- 單表
- 主鍵必須唯一,且單調遞增
- 有唯一鍵的,盡量建立唯一鍵
- where條件用得比較多的字段
- 查詢條件多的,用聯合索引,如果帶有范圍條件的,將這個列,放在聯合索引的后面
-
多表查詢時候的索引
- on條件后面列建立索引,select a.a1, a.a2, b.b1, b.b2 from a join b on a.a1 = b.b1; 這種sql兩個列的類型要相同。
- 多用join代in查詢
-
其它
- order by, group by的列
- UPDATE、DELETE 的 WHERE 條件列
2. 索引容易失效的場景
①. 全值匹配, 聯合索引下,每個列都用上索引
②. 最左匹配原則
create index idx_name_age_classId on student(name, age, classId);-- 不生效 explain select * from student where age = 1;查詢上面的語句不會走索引, 如果是name作為條件,索引才會生效
下面走了索引,name & age
explain select id, name, age, classId from student where name = 'jack' and age = 1;
③. 排序字段應該放最后
④ 不等于, (<>, !=) 索引失效
⑤ is null 有效, is not null 索引失效
⑥ like查詢以通配符開始的失效,如果不走索引覆蓋的話。用es。
⑦ 函數導致索引失效
⑧ or 前后存在非索引的列, 索引失效
⑨ 數據庫和表的字符集統一使用utf8mb4
3. 連接查詢索引優化
① 左連接 左邊的表是驅動表 右邊的表是被驅動表.
② 內連接, 小表驅動大表, 小表是結果集少的
③ 為join的字段創建索引,并且join的字段類型要一致
保證被驅動表的JOIN字段已經創建了索引
需要JOIN 的字段,數據類型保持絕對一致。
LEFT JOIN 時,選擇小表作為驅動表, 大表作為被驅動表 。減少外層循環的次數。
INNER JOIN 時,MySQL會自動將 小結果集的表選為驅動表 。選擇相信MySQL優化策略。
能夠直接多表關聯的盡量直接關聯,不用子查詢。(減少查詢的趟數)
不建議使用子查詢,建議將子查詢SQL拆開結合程序多次查詢,或使用 JOIN 來代替子查詢。
衍生表建不了索引。
4. order by,group by
-
排序, 單個字段, 請建立索引。多個字段建立聯合索引。 盡可能的使用index索引排序, 如果不能, 使用file sort 文件排序,加大內存參數
order by 有兩種排序方法:1,走索引;2,file sort 內存排序。索引快,如果用內存排序,吃資源。
- group by 也請走索引…
group by 使用索引的原則幾乎跟order by一致 ,group by 即使沒有過濾條件用到索引,也可以直接使用索引。
group by 先排序再分組,遵照索引建的最佳左前綴法則
當無法使用索引列,增大 max_length_for_sort_data 和 sort_buffer_size 參數的設置
where效率高于having,能寫在where限定的條件就不要寫在having中了
減少使用order by,和業務溝通能不排序就不排序,或將排序放到程序端去做。Order by、group by、distinct這些語句較為耗費CPU,數據庫的CPU資源是極其寶貴的。
包含了order by、group by、distinct這些查詢的語句,where條件過濾出來的結果集請保持在1000行以內,否則SQL會很慢。
5. 覆蓋索引
對聯合索引來說的,查詢直接查索引。不會回表,一次查詢出來結果。查詢的列都是索引,查詢條件也是所有列。
所以這里的like統配匹配不會失效。
6. 索引下推
這個也是聯合索引中出現的,最大的特征是,用explain分析工具,查詢extra信息,顯示Using index condition。
① 索引的每個列和查詢的值比較一遍
② 匹配到的索引,再進行回表拿到結果。
ICP的使用條件:
① 只能用于二級索引(secondary index)
②explain顯示的執行計劃中type值(join 類型)為 range 、 ref 、 eq_ref 或者 ref_or_null 。
③ 并非全部where條件都可以用ICP篩選,如果where條件的字段不在索引列中,還是要讀取整表的記錄
到server端做where過濾。
④ ICP可以用于MyISAM和InnnoDB存儲引擎
⑤ MySQL 5.6版本的不支持分區表的ICP功能,5.7版本的開始支持。
⑥ 當SQL使用覆蓋索引時,不支持ICP優化方法。
總結
- 上一篇: python matplotlib阶段性
- 下一篇: java single instance