MySQL優化器的第一法則
- 在複合索引中,MySQL在遇到返回查詢(,BETWEEN)時,將停止中止剩餘部分(索引)的使用;但是使用IN(…)的"範圍查詢"則可以繼續往右使用索引(的更多部分)
所用索引進行排序
- SELECT * FROM PLAYERS ORDER BY SCOREDESC LIMIT 10
- 將使用索引 KEY(SCORE)
- 不使用索引將進行非常昂貴的“filesort”操作(externalsort)
- 常常使用組合索引進行查詢
- SELECT * FROM PLAYERS WHERE COUNTRY=“US”ORDER BY SCORE DESC LIMIT 10
- 最佳選擇是 KEY(COUNTRY,SCORE)
高效排序的聯合索引
- 變得更加受限!
- KEY(A,B)
- 以下情形將會使用索引進行排序
- ORDER BY A - 對索引首字段進行排序
- A=5 ORDER BY B - 對第一個字段進行點查詢,對第二個字段進行排序
- ORDER BY A DESC, B DESC - 對兩個字段進行相同的順序進行排序
- A>5 ORDER BY A - 對首字段進行範圍查詢,並對首字段進行排序
- 以下情形將不使用索引進行排序
- ORDER BY B - 對第二個字段進行排序(未使用首字段)
- A>5 ORDER BY B – 對首字段進行範圍查詢,對第二個字段進行排序
- A IN(1,2) ORDER BY B - 對首字段進行IN查詢,對第二個字段進行排序
- ORDER BY A ASC, B DESC - 對兩個字段進行不同順序的排序
MySQL使用索引排序的規則
- 不能對兩個字段進行不同順序的排序
- 對非ORDER BY部分的字段只能使用點查詢(=)– 在這種情形下,IN()也不行
避免讀取數據(只讀取索引)
- “覆蓋索引”– 這裡指 適用於特定查詢的索引,而不是一種索引的類型
- 只讀取索引,而不去讀取數據
- SELECT STATUS FROM ORDERS WHERECUSTOMER_ID=123
- KEY(CUSTOMER_ID,STATUS)
- 索引通常比數據本身要小
- (索引)讀取起來更有次序– 讀取數據指針通常是隨機的
Min/Max的優化
- 索引可以幫助優化 MIN()/MAX() 這類的統計函數– 但只包含以下這些:
- SELECT MAX(ID) FROM TBL;
- SELECT MAX(SALARY) FROM EMPLOYEEGROUP BY DEPT_ID
- 將受益於 KEY(DEPT_ID,SALARY)
- “Using index for group-by”
聯表查詢中索引的使用
- MySQL 使用 “嵌套循環(Nested Loops)”進行聯表查詢
- SELECT * FROM POSTS,COMMENTS WHEREAUTHOR=“Peter” AND COMMENTS.POST_ID=POSTS.ID
- 掃描表POSTS查詢所有複合條件的 posts
- 循環posts 在表COMMENTS 中查找 每個post的所有comments
- 使每個關聯的表(關聯字段)都使用上索引顯得非常的重要
- 索引只有在被查詢的字段上是必要的– POSTS.ID字段的索引再本次查詢中是用不上的
- 重新設計不能很好的所有索引的聯合查詢吧
使用多索引
- MySQL可以使用超過1個索引
- “索引合併”
- SELECT * FROM TBL WHERE A=5 AND B=6– 可以分別使用索引 KEY(A)和 KEY(B)
- 索引 KEY(A,B) 是更好的選擇
- SELECT * FROM TBL WHERE A=5 OR B=6– 兩個索引同時分別被使用
- 索引 KEY(A,B) 在這個查詢中無法使用
前綴索引
- 你可以在字段最左前綴建立索引
- ALTER TABLE TITLE ADD KEY(TITLE(20));
- 需要對BLOB/TEXT類型的字段建立索引
- 能顯著的減少空間使用
- 不能用於覆蓋索引
- 選擇前綴長度成為一個問題
閱讀更多 思夢PHP 的文章