MySQL 优化 —— MySQL 如何使用索引
引言
本文翻譯自MySQL 官網 :How MySQL Uses Indexes?,MySQL 版本 5.7 。
提升 SELECT 操作性能最好的方式就是在查詢的一列或多列上建立索引。索引的行為類似指向表數據的指針,可以讓查詢能夠快速判斷哪個記錄滿足 WHERE 子句中的條件,然后取得這些記錄的其他字段的值。所有的 MySQL 數據類型都支持索引。
雖然在可能用于查詢的所有字段上都建立索引的做法是非常誘人的,但是不必要的索引既浪費存儲空間,同時也浪費了MySQL 決定用哪個索引的時間。索引也會增加 insert、update、delete 等更新操作的開銷,因為每個索引都必須更新。你必須找到恰當的平衡點使用最理想的索引集合來實現快速的查詢。
MySQL 如何使用索引
索引被用于快速查找特定的列值對應的記錄。沒有索引,MySQL 就必須得從表的第一行開始,然后讀取整張表才能找到符合條件的記錄。表越大,花費的時間就越多。如果表里有一個正好適合查詢情況的索引,MySQL 就可以快速在表中確定對應的位置而不需要搜索所有數據。這比連續讀取每一行要快不少。
絕大多數MySQL 索引(PRIMARY KEY,UNIQUE ,INDEX??和 FULLTEXT)都以 B 樹的形式存儲。例外的情況:空間數據類型(spatial data type)的索引使用 R 樹,MEMORY 存儲引擎也支持 hash 索引。InnoDB 使用倒排表(inverted lists)來實現 FULLTEXT 索引。
下面的討論描述了索引使用的一般情況。關于 hash 索引的具體特征請移步至:https://dev.mysql.com/doc/refman/5.7/en/index-btree-hash.html?(未來我會對該章進行單獨翻譯,并會更新此處的連接)
MySQL 會在以下操作中使用索引:
1、用于快速找到匹配 WHERE 子句的記錄。
2、用于縮小數據檢索范圍。如果有多個索引可供選擇,MySQL normally uses the index that finds the smallest number of rows (the most selective index). MySQL 通常會使用可以找到最小記錄數的索引(最具選擇性的索引)。
3、如果表有一個復合索引,那么索引中任何最左側的前綴都可以被優化器使用。例如,如果你有一個三列復合索引如(col1, col2, col3) ,那么你有三種索引搜索的可選方案:(col1)、(col1,col2)、以及(col1,col2, col3)。
4、當執行連接查詢時取得其他表中的記錄,如果索引字段聲明了同樣的類型和大小,那么 MySQL 會更有效地利用該列上的索引。在這種語境下,VARCHAR 和 CHAR 如果大小一致,那么就可以認為是同種類型。例如, VARCHAR(10) 和 CHAR(10) 具有相同的大小,但是?VARCHAR(10) 和 CHAR(15) 就不是了。
對于比較非二進制字符串列值,兩個列必須具有相同的字符集。例如,比較 utf8 的字段和 latin1 的字段就會影響到使用索引。
比較不同類型的字段(如字符串和時間類型或數值類型等),如果兩個值不經過轉換就無法直接比較的話,那么同樣會無法使用索引。有一個給定的數值類型 1 ,可能會與'1','? 1','00001' 或 '01.e1' 這樣的字符串比較。那么這種情況就無法使用任何索引。
5、To find the?MIN()?or?MAX()?value for a specific indexed column?key_col.?This is optimized by a preprocessor that checks whether you are using?WHERE?key_part_N?=?constant?on all key parts that occur before?key_col?in the index. In this case, MySQL does a single key lookup for each?MIN()?or?MAX()expression and replaces it with a constant. If all expressions are replaced with constants, the query returns at once. For example:?
SELECT MIN(key_part2),MAX(key_part2)FROM tbl_name WHERE key_part1=10;(上面這段話我沒有理解官方文檔的意思,有能翻譯的同學幫忙評論區留個言!非常感謝)
6、用于排序或分組已經使用索引的左前綴排好序或分好組的表(例如,ORDER BY key_part1, key_part2)。如果所有字段都使用 DESC ,那么索引就會以相反的順序讀取。
7、有些情況,優化器可以優化查詢,不需要訪問原始記錄,就可以獲取數據。(可以獲取全部查詢必要信息的索引叫做覆蓋索引)如果查詢列表只查詢了那些包含在索引中的字段,那么查詢的值可以以更快的速度從索引樹中獲取:
SELECT key_part3 FROM tbl_nameWHERE key_part1=1索引對于小表不那么重要,對于那些需要查詢絕大多數行或全部行的大表也不那么重要。如果查詢需要訪問絕大多數記錄,那么按序讀取會比使用索引更快。連續的讀取可以最小化磁盤搜索,即使并不是所有記錄都需要查詢。
總結
以上是生活随笔為你收集整理的MySQL 优化 —— MySQL 如何使用索引的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: git 命令详解和Android Stu
- 下一篇: 监控mysql锁定状态_企业实战Mysq