MYSQL索引最佳實踐

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類型的字段建立索引
  • 能顯著的減少空間使用
  • 不能用於覆蓋索引
  • 選擇前綴長度成為一個問題


分享到:


相關文章: