搜尋
首頁資料庫mysql教程大揭秘! MySQL資料庫之索引

大揭秘! MySQL資料庫之索引

1、概述

索引是一種儲存引擎用於快速尋找記錄的資料結構,透過合理的使用資料庫索引可以大幅提高系統的存取效能,接下來主要介紹在

MySql資料庫中索引類型,以及如何建立出更合理且有效率的索引技巧。

註:這裡主要針對的是InnoDB儲存引擎的B Tree索引資料結構

#2、索引的優點

大幅減輕了伺服器需要掃描的資料量,從而提高了資料的檢索速度

幫助伺服器避免排序和臨時表

可以將隨機I/O變為順序I/O

3、索引的建立

#3.1、主鍵索引

ALTER TABLE 'table_name' ADD PRIMARY KEY 'index_name' ('column');

3.2、唯一索引

#
ALTER TABLE 'table_name' ADD UNIQUE 'index_name' ('column');

3.3、普通索引

ALTER TABLE 'table_name' ADD INDEX 'index_name' ('column');

3.4、全文索引

ALTER TABLE 'table_name' ADD FULLTEXT 'index_name' ('column');

3.5、組合索引

ALTER TABLE 'table_name' ADD INDEX 'index_name' ('column1', 'column2', ...);

4、B Tree的索引規則

#建立一個測試的使用者表

DROP TABLE IF EXISTS user_test;CREATE TABLE user_test(    id int AUTO_INCREMENT PRIMARY KEY,
    user_name varchar(30) NOT NULL,
    sex bit(1) NOT NULL DEFAULT b'1',
    city varchar(50) NOT NULL,
    age int NOT NULL) ENGINE=InnoDB DEFAULT CHARSET=utf8;

建立一個組合索引: ALTER TABLE user_test ADD INDEX idx_user(user_name , city , age);

4.1、索引有效的查詢

#4.1.1、全值符合

全值匹配指的是和索引中的所有列進行匹配,如:以上面創建的索引為例,在where條件後可同時查詢(user_name,city,age)為

條件的資料。

註:與where後查詢條件的順序無關,這裡是很多同學容易誤解的一個地方

SELECT * FROM user_test WHERE user_name = 'feinik' AND age = 26 AND city = '广州';

4.1.2、匹配最左前綴

比對最左前綴是指優先匹配最左索引列,如:上面建立的索引可用於查詢條件為:(user_name )、(user_name, city)、(user_name , city , age)

註:滿足最左前綴查詢條件的順序與索引列的順序無關,如:(city, user_name)、(age, city, user_name)

4.1.3、符合列前綴

#指符合列值的開頭部分,如:查詢使用者名稱以feinik開頭的所有使用者

SELECT * FROM user_test WHERE user_name LIKE 'feinik%';

4.1.4、符合範圍值

如:查詢用戶名以feinik開頭的所有用戶,這裡使用了索引的第一列

SELECT * FROM user_test WHERE user_name LIKE 'feinik%';

4.2、索引的限制

1、where查詢條件中不包含索引列中最左邊的索引列,則無法使用到索引查詢,如:

SELECT * FROM user_test WHERE city = '广州';

SELECT * FROM user_test WHERE age= 26;


SELECT * FROM user_test WHERE city = '广州' AND age = '26';

2、即使where的查詢條件是最左索引列,也無法使用索引查詢使用者名稱以feinik結尾的使用者

SELECT * FROM user_test WHERE user_name like '%feinik';

3、如果where查詢條件中有某個列的範圍查詢,則其右邊的所有欄位都無法使用索引最佳化查詢,如:

SELECT * FROM user_test WHERE user_name = 'feinik' AND city LIKE '广州%' AND age = 26;

5、高效率的索引策略

5.1、索引列不能是表達式的一部分,也不能作為函數的參數,否則無法使用索引查詢。

SELECT * FROM user_test WHERE user_name = concat(user_name, 'fei');

5.2、前綴索引

有時候需要索引很長的字元列,這會增加索引的儲存空間以及降低索引的效率,一種策略是可以使用哈希索引,還有一種就是可以使

用前綴索引,前綴索引是選擇字元列的前n個字元作為索引,這樣可以大大節約索引空間,從而提高索引效率。

5.2.1、前綴索引的選擇性

#前綴索引要選擇足夠長的前綴以保證高的選擇性,同時又不能太長,我們可以透過以下方式來計算出適當的前綴索引的選擇長度值:

(1)

SELECT COUNT(DISTINCT index_column)/COUNT(*) FROM table_name; -- index_column代表要添加前缀索引的列

註:透過以上方式來計算出前綴索引的選擇性比值,比值越高說明索引的效率也越有效率。

(2)

#
SELECTCOUNT(DISTINCT LEFT(index_column,1))/COUNT(*),COUNT(DISTINCT LEFT(index_column,2))/COUNT(*),COUNT(DISTINCT
 LEFT(index_column,3))/COUNT(*)
 ...FROM table_name;

##「註:透過上述語句逐步找到最接近(1)中的前綴索引的選擇性比值,那麼就可以使用對應的字元截取長度來做前綴索引了

5.2.2、前綴索引的建立

ALTER TABLE table_name ADD INDEX index_name (index_column(length));

5.2.3、使用前綴索引的注意點

前綴索引是一種能讓索引更小,更快的有效方法,但是MySql無法使用前綴索引做ORDER BY 和GROUP BY以及使用前綴索引做覆蓋

掃描。

5.3、选择合适的索引列顺序

在组合索引的创建中索引列的顺序非常重要,正确的索引顺序依赖于使用该索引的查询方式,对于组合索引的索引顺序可以通过经验

法则来帮助我们完成:将选择性最高的列放到索引最前列,该法则与前缀索引的选择性方法一致,但并不是说所有的组合索引的顺序

都使用该法则就能确定,还需要根据具体的查询场景来确定具体的索引顺序。

5.4 聚集索引与非聚集索引

1、聚集索引

聚集索引决定数据在物理磁盘上的物理排序,一个表只能有一个聚集索引,如果定义了主键,那么InnoDB会通过主键来聚集数据,如

果没有定义主键,InnoDB会选择一个唯一的非空索引代替,如果没有唯一的非空索引,InnoDB会隐式定义一个主键来作为聚集索

引。

聚集索引可以很大程度的提高访问速度,因为聚集索引将索引和行数据保存在了同一个B-Tree中,所以找到了索引也就相应的找到了

对应的行数据,但在使用聚集索引的时候需注意避免随机的聚集索引(一般指主键值不连续,且分布范围不均匀),如使用UUID来作

为聚集索引性能会很差,因为UUID值的不连续会导致增加很多的索引碎片和随机I/O,最终导致查询的性能急剧下降。

2、非聚集索引

与聚集索引不同的是非聚集索引并不决定数据在磁盘上的物理排序,且在B-Tree中包含索引但不包含行数据,行数据只是通过保存在

B-Tree中的索引对应的指针来指向行数据,如:上面在(user_name,city, age)上建立的索引就是非聚集索引。

5.5、覆盖索引

如果一个索引(如:组合索引)中包含所有要查询的字段的值,那么就称之为覆盖索引,如:

SELECT user_name, city, age FROM user_test WHERE user_name = 'feinik' AND age > 25;

因为要查询的字段(user_name, city, age)都包含在组合索引的索引列中,所以就使用了覆盖索引查询,查看是否使用了覆盖索引可

以通过执行计划中的Extra中的值为Using index则证明使用了覆盖索引,覆盖索引可以极大的提高访问性能。

5.6、如何使用索引来排序

在排序操作中如果能使用到索引来排序,那么可以极大的提高排序的速度,要使用索引来排序需要满足以下两点即可。

1、ORDER BY子句后的列顺序要与组合索引的列顺序一致,且所有排序列的排序方向(正序/倒序)需一致

2、所查询的字段值需要包含在索引列中,及满足覆盖索引

通过例子来具体分析

在user_test表上创建一个组合索引

ALTER TABLE user_test ADD INDEX index_user(user_name , city , age);

可以使用到索引排序的案例

1、SELECT user_name, city, age FROM user_test ORDER BY user_name;

2、SELECT user_name, city, age FROM user_test ORDER BY user_name, city;

3、SELECT user_name, city, age FROM user_test ORDER BY user_name DESC, city DESC;

4、SELECT user_name, city, age FROM user_test WHERE user_name = 'feinik' ORDER BY city;

注:第4点比较特殊一点,如果where查询条件为索引列的第一列,且为常量条件,那么也可以使用到索引

无法使用索引排序的案例

1、sex不在索引列中

SELECT user_name, city, age FROM user_test ORDER BY user_name, sex;

2、排序列的方向不一致

SELECT user_name, city, age FROM user_test ORDER BY user_name ASC, city DESC;

3、所要查询的字段列sex没有包含在索引列中

SELECT user_name, city, age, sex FROM user_test ORDER BY user_name;

4、where查询条件后的user_name为范围查询,所以无法使用到索引的其他列

SELECT user_name, city, age FROM user_test WHERE user_name LIKE 'feinik%' ORDER BY city;

5、多表连接查询时,只有当ORDER BY后的排序字段都是第一个表中的索引列(需要满足以上索引排序的两个规则)时,方可使用索

引排序。如:再创建一个用户的扩展表user_test_ext,并建立uid的索引。

DROP TABLE IF EXISTS user_test_ext;CREATE TABLE user_test_ext(    id int AUTO_INCREMENT PRIMARY KEY,

 uid int NOT NULL,
 u_password VARCHAR(64) NOT NULL) ENGINE=InnoDB DEFAULT CHARSET=utf8;ALTER TABLE user_test_ext ADD INDEX 
 index_user_ext(uid);

走索引排序

SELECT user_name, city, age FROM user_test u LEFT JOIN user_test_ext ue ON u.id = ue.uid ORDER BY u.user_name;

不走索引排序

SELECT user_name, city, age FROM user_test u LEFT JOIN user_test_ext ue ON u.id = ue.uid ORDER BY ue.uid;

6、总结

本文主要讲了B+Tree树结构的索引规则,不同索引的创建,以及如何正确的创建出高效的索引技巧来尽可能的提高查询速度,当然了

关于索引的使用技巧不单单只有这些,关于索引的更多技巧还需平时不断的积累相关经验。

以上是大揭秘! MySQL資料庫之索引的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文轉載於:www.liqingbo.cn。如有侵權,請聯絡admin@php.cn刪除
MySQL的許可與其他數據庫系統相比如何?MySQL的許可與其他數據庫系統相比如何?Apr 25, 2025 am 12:26 AM

MySQL使用的是GPL許可證。 1)GPL許可證允許自由使用、修改和分發MySQL,但修改後的分發需遵循GPL。 2)商業許可證可避免公開修改,適合需要保密的商業應用。

您什麼時候選擇InnoDB而不是Myisam,反之亦然?您什麼時候選擇InnoDB而不是Myisam,反之亦然?Apr 25, 2025 am 12:22 AM

選擇InnoDB而不是MyISAM的情況包括:1)需要事務支持,2)高並發環境,3)需要高數據一致性;反之,選擇MyISAM的情況包括:1)主要是讀操作,2)不需要事務支持。 InnoDB適合需要高數據一致性和事務處理的應用,如電商平台,而MyISAM適合讀密集型且無需事務的應用,如博客系統。

在MySQL中解釋外鍵的目的。在MySQL中解釋外鍵的目的。Apr 25, 2025 am 12:17 AM

在MySQL中,外鍵的作用是建立表與表之間的關係,確保數據的一致性和完整性。外鍵通過引用完整性檢查和級聯操作維護數據的有效性,使用時需注意性能優化和避免常見錯誤。

MySQL中有哪些不同類型的索引?MySQL中有哪些不同類型的索引?Apr 25, 2025 am 12:12 AM

MySQL中有四種主要的索引類型:B-Tree索引、哈希索引、全文索引和空間索引。 1.B-Tree索引適用於範圍查詢、排序和分組,適合在employees表的name列上創建。 2.哈希索引適用於等值查詢,適合在MEMORY存儲引擎的hash_table表的id列上創建。 3.全文索引用於文本搜索,適合在articles表的content列上創建。 4.空間索引用於地理空間查詢,適合在locations表的geom列上創建。

您如何在MySQL中創建索引?您如何在MySQL中創建索引?Apr 25, 2025 am 12:06 AM

toCreateAnIndexinMysql,usethecReateIndexStatement.1)forasingLecolumn,使用“ createIndexIdx_lastNameEnemployees(lastName); 2)foracompositeIndex,使用“ createIndexIndexIndexIndexIndexDx_nameOmplayees(lastName,firstName,firstName);” 3)forauniqe instex,creationexexexexex,

MySQL與Sqlite有何不同?MySQL與Sqlite有何不同?Apr 24, 2025 am 12:12 AM

MySQL和SQLite的主要區別在於設計理念和使用場景:1.MySQL適用於大型應用和企業級解決方案,支持高性能和高並發;2.SQLite適合移動應用和桌面軟件,輕量級且易於嵌入。

MySQL中的索引是什麼?它們如何提高性能?MySQL中的索引是什麼?它們如何提高性能?Apr 24, 2025 am 12:09 AM

MySQL中的索引是數據庫表中一列或多列的有序結構,用於加速數據檢索。 1)索引通過減少掃描數據量提升查詢速度。 2)B-Tree索引利用平衡樹結構,適合範圍查詢和排序。 3)創建索引使用CREATEINDEX語句,如CREATEINDEXidx_customer_idONorders(customer_id)。 4)複合索引可優化多列查詢,如CREATEINDEXidx_customer_orderONorders(customer_id,order_date)。 5)使用EXPLAIN分析查詢計劃,避

說明如何使用MySQL中的交易來確保數據一致性。說明如何使用MySQL中的交易來確保數據一致性。Apr 24, 2025 am 12:09 AM

在MySQL中使用事務可以確保數據一致性。 1)通過STARTTRANSACTION開始事務,執行SQL操作後用COMMIT提交或ROLLBACK回滾。 2)使用SAVEPOINT可以設置保存點,允許部分回滾。 3)性能優化建議包括縮短事務時間、避免大規模查詢和合理使用隔離級別。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser是一個安全的瀏覽器環境,安全地進行線上考試。該軟體將任何電腦變成一個安全的工作站。它控制對任何實用工具的訪問,並防止學生使用未經授權的資源。

PhpStorm Mac 版本

PhpStorm Mac 版本

最新(2018.2.1 )專業的PHP整合開發工具

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。

MantisBT

MantisBT

Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

VSCode Windows 64位元 下載

VSCode Windows 64位元 下載

微軟推出的免費、功能強大的一款IDE編輯器