1. 程式人生 > 其它 >mysql :索引(補充)

mysql :索引(補充)


EXPLAIN SELECT SQL_NO_CACHE * FROM emp WHERE emp.age=30 and deptid=4 AND emp.name = ‘abcd’;

根據前文所說 建立索引
CREATE INDEX idx_age_deptid_name on emp(age,deptid,name);
1.最左匹配原則
建立索引(a,b,c)相當於建立了 (a) (a,b) (a,b,c)三個索引
如果此時,sql語句換成

EXPLAIN SELECT SQL_NO_CACHE * FROM emp WHEREemp.age=30ANDemp.name = ‘abcd’;
或者
EXPLAIN SELECT SQL_NO_CACHE * FROM emp WHEREemp.deptid=1ANDemp.name = ‘abcd’;

之前的索引並不起作用,複合索引 查詢從索引的最左前列開始並且不跳過索引中的列。

2.
計算和函式會導致索引失效:
想要使用索引 必須把列單獨表示

3.範圍右邊的列索引失效

4.!= <> 索引失效

5.is not null 無法使用索引。is null 可以

6.like 以% 開頭索引失效

7.型別轉換導致索引失效

二。關聯查詢
EXPLAIN SELECT SQL_NO_CACHE * FROM class LEFT JOIN book ON class.card = book.card;
1.採取左連線,索引加在右表上
CREATE INDEX idx_book_card ON book(card);

2.換成inner join(MySQL自動選擇驅動表)
inner join 時,mysql會自動將小結果集的表選為驅動表。選擇相信mysql優化策略。

三、排序
排序必須包含在索引中,順序必須與索引中順序完全相同 或者 反向倒序
EXPLAIN SELECT SQL_NO_CACHE * FROM emp WHERE age =30 AND empno <101000 ORDER BY NAME ;

CREATE INDEX idx_age_empno_name ON emp (age,empno,NAME);
因為empno是一個範圍過濾,所以索引後面的欄位不會再使用索引了。
此時只能建立一個兩個欄位的索引。
當【範圍條件】和【group by 或者 order by】的欄位出現二選一時,優先觀察條件欄位的過濾數量,如果過濾的資料足夠多,而需要排序的資料並不多時,優先把索引放在範圍欄位上。反之,亦然。
雙路排序和單路排序
增大sort_buffer_size引數的設定
增大max_length_for_sort_data引數的設定
減少select 後面的查詢的欄位。 禁止使用select *
order by 時select * 會讓索引失效
group by沒有過濾條件,也可以用上索引。Order By 必須有過濾條件才能使用上索引。
覆蓋索引:select到from之間的欄位使用了索引
儘量使用覆蓋索引。不要使用select *