MySQL—【加餐1】高效查询方法
高效查詢方法
隨著數據量的增大,企業對查詢的速度要求也越來越高,掌握高效查詢的方法對于平時的工作是非常有幫助的。下面我們就一起來看一下有哪些方法可以高效查詢。
為了提高數據的查詢速度,最常用的解決方案就是給表中變量創建索引。我們可以將索引理解成書的目錄,如果一本書沒有目錄,那檢索起來可能就比較麻煩,一旦有了目錄,我們就可以根據目錄進行索引,很快地找到我們需要的內容。同樣的道理,如果數據表中有了索引,就可以大大提高MySQL的執行效率。
1. 常見索引類型
索引有很多種類型,下面我們一起來學習幾個比較常用的索引類型。
(1)普通索引
普通索引是一種沒有任何約束的索引,它對表中變量的值不做任何的限制,不管變量的值是否存在重復值或缺失值(也就是NULL值),所以普通索引是使用最頻繁的一種索引。
可以通過兩種方式來建立普通索引:
- 創建新表時設定某個字段為普通索引
- 基于已有的表添加普通索引
以校園一卡通消費數據stu_card為例,查詢出交易時間在2013年9月1日的所有記錄。
# 沒有創建索引之前的條件查詢 SELECT * FROM stu_card WHERE custom_date BETWEEN '2013-09-01 00:00:00' AND '2013-09-01 23:59:59';結果顯示,1200萬行數據,查詢出滿足條件的3萬多行數據大約需要14.907s的時間。
# 創建索引 CREATE INDEX date_index ON stu_card(custom_date); # 執行查詢 SELECT * FROM stu_card WHERE custom_date BETWEEN '2013-09-01 00:00:00' AND '2013-09-01 23:59:59';結果顯示,基于普通索引的查詢代碼,獲取滿足條件的交易記錄只需要0.1秒左右,速度有明顯提升。
(2)唯一索引
相對于普通索引來說,唯一索引對字段或者字段組合是有約束的,也就是必選確保字段或者字段組合的每一個觀測值都是唯一的,不能存在重復值。如果字段中還有多個空白字符串,也算是有重復值,因為空字符串代表一種值。
一個表中可以有多個唯一索引,創建唯一索引的方法也有兩種,與創建普通索引類似。可以在創建新表的時候設置唯一索引,也可以對已有表添加唯一索引。
# 兩種唯一索引的創建方法 # 建表時創建索引 CREATE TABLE <table_name_> ( field1 data_type1, field2 data_type2, field3 data_type3, ……UNIQUE <index_name>(field1,field2)); # 對已有表添加索引,可以通過創建法或修改法 CREATE UNIQUE INDEX <index_name> ON <table_name_>(field_list); #基于已有的表創建索引 ALTER TABLE <table_name_> ADD UNIQUE <index_name> (field_list); #基于已有表修改索 引接下來以某平臺的旅游交易數據為例,對比無索引和基于唯一索引的兩種查詢的速度。
# 新建數據表tourism_orders CREATE TABLE tourism_orders( userid VARCHAR(20), orderid VARCHAR(12), orderTime VARCHAR(15), orderType VARCHAR(2), city VARCHAR(20), country VARCHAR(20), continent VARCHAR(10)); # 往表中插數據 LOAD DATA local INFILE '/Users/zhucan/Desktop/tourism_orders.csv' INTO TABLE tourism_orders FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n' IGNORE 1 ROWS; # 查詢數據前幾行 SELECT * FROM tourism_orders LIMIT 10; # 無索引下的條件查詢 SELECT * FROM tourism_orders WHERE userid = '100000001445'; # 約0.016秒 # 創建兩個組合變量的唯一索引 CREATE UNIQUE INDEX id_idx ON tourism_orders(userid, orderid); # 再次執行查詢語句 SELECT * FROM tourism_orders WHERE userid = '100000001445'; # 幾乎為0秒(3)主鍵索引
主鍵索引對字段的要求最為嚴格,必須確保字段中的值既不存在重復值也不存在缺失值。與普通索引和唯一索引不同的是,一張表中只能有一個主鍵索引。關于主鍵索引的創建語法:
這里使用用戶注冊數據和用戶交易數據,來驗證主鍵索引構建前后查詢速度的差異。
# 創建用戶注冊表和RFM表 CREATE TABLE regit_info ( uid VARCHAR(10), gender TINYINT, age TINYINT, regit_date DATE ); CREATE TABLE RFM ( uid VARCHAR(10), R INT, F TINYINT, M DECIMAL(10,2) ); # 批量導入數據 LOAD DATA local INFILE '/Users/zhucan/Desktop/regit_info.csv' INTO TABLE regit_info FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n' IGNORE 1 ROWS; LOAD DATA local INFILE '/Users/zhucan/Desktop/RFM.csv' INTO TABLE RFM FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n' IGNORE 1 ROWS; # 內連接完成兩表字段的合并 SELECT t1.*,t2.R,t2.F,t2.M FROM regit_info AS t1 INNER JOIN RFM AS t2 ON t1.uid=t2.uid LIMIT 10000; # 添加主鍵索引 ALTER TABLE regit_info ADD PRIMARY key (uid); ALTER TABLE RFM ADD PRIMARY key (uid); # 再次執行查詢 SELECT t1.*,t2.R,t2.F,t2.M FROM regit_info AS t1 INNER JOIN RFM AS t2 ON t1.uid=t2.uid2. 索引的查詢
如果想要對表進行操作,通常需要知道表中是否已經存在索引,如果存在這些索引又是什么類型的,名稱是什么,是設置在哪些字段上了等等。只有了解表中的索引信息,我們才能進一步管理索引。
# 查詢索引信息語法 SHOW INDEX FROM <table_name_>;查詢用戶注冊表regit_info和旅游交易表tourism_orders的索引信息:
SHOW INDEX FROM regit_info; SHOW INDEX FROM tourism_orders;3. 刪除索引
# 刪除索引語法 DROP INDEX <index_name> ON <table_name_>; #用于刪除普通索引和唯一索引 ALTER TABLE <table_name_> DROP INDEX <index_name>; #用于刪除普通索引和唯一索引 ALTER TABLE <table_name_> DROP PRIMARY KEY; #用于刪除主鍵索引刪除用戶注冊表regit_info中的主鍵索引:
ALTER TABLE regit_info DROP PRIMARY KEY; #刪除索引 SHOW INDEX FROM regit_info; #查看索引刪除旅游交易表tourism_orders中的唯一索引:
DROP INDEX id_idx ON tourism_orders; #刪除索引 SHOW INDEX FROM tourism_orders; #查看索引4 . 關于索引的注意事項
盡管索引有提速的功能(可以提高響應的select的效率),但是也不能濫用,因為它會降低數據表的寫操作速度(insert 和 update的效率會變低),也會占用一定的磁盤空間。所以在創建和使用索引的過程
中,有一些事項需要大家注意:
4.1 何時創建索引
- WHERE 關鍵詞后面的字段創建索引,可以加快條件判斷速度
- ORDER BY關鍵詞后面的字段創建索引,可以加快排序速度
- 表連接關鍵詞 ON 后面的字段創建索引,可以加快表連接速度
- 包含大量NULL的字段不適合創建索引,因為索引不可以包含NULL值
- 包含大量重復值的字段不適合創建索引,因為基于索引的查詢規則,在進行條件篩選的時候
- 可能會產生大量的數據行,此時索引并不能加快數據庫搜索過程中的掃描速度
4.2 索引無效的情況
- WHERE 關鍵詞后面的條件表達式中如果使用IN、OR、!=或者<>,均會導致索引無效。解決方法是將“!=”或者“<>”替換為">AND<",將"IS NOT NULL"替換為">=CHR(0)"。
- 篩選或排序過程中,如果對索引列使用函數,則索引失效。
- 篩選過程中,如果字符型字段寫成了數值型的數字,則索引失效(比如,用戶id字段是字符型,那篩選的時候需要寫where uid = “1”)
- 使用模糊查詢的時候,如果將通配符放在開頭,則索引失效(like “%aaa%” 不會使用索引而like“aaa%”可以使用索引)
- 對于多列的組合索引,遵循左原則,例如對字段A,B,C設置索引 INDEX(A,B,C) ,則"A>0" “A=1 AND B>10”、“A=10 AND B<6 AND C>100"都可以使組合索引有效,但是"B>10”、"B<6 AND C>100"都會導致組合索引失效。
- 在JOIN操作中,關鍵詞ON后面的字段類型要保持一致(也就是左表中這個字段的數據類型和右表中同一字段的數據類型要保持一致),否則索引無效。
4.3 索引數量并不是越多越好
原則上,一個表的索引數量最好不要超過6個(當然也得看你的數據的原始字段個數)
總結
以上是生活随笔為你收集整理的MySQL—【加餐1】高效查询方法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MySQL——数据库的增删改操作
- 下一篇: 特征选择(feature_selecti