日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

MySQL索引知识总结

發布時間:2025/3/21 数据库 18 豆豆
生活随笔 收集整理的這篇文章主要介紹了 MySQL索引知识总结 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

對MySQL索引知識的總結筆記。

普通索引

索引是一種數據結構,主要用于性能的提高。

比如我們有一個表t_users,有4個字段:

1234567 create table t_users ( id bigint(20) not null auto_increment, name varchar(255) not null,age bigint(20) not null, num bigint(20) not null,primary key (id)) ENGINE=InnoDB DEFAULT CHARSET=utf8;

往這個表中插入100w條數據,name字段是format-1到100w,age字段也是1-100w,num字段是個隨機的10以內的數字。然后執行sql語句進行查詢:

1234567 mysql> select * from t_users where name = 'format-500000';+--------+---------------+--------+-----+| id | name | age | num |+--------+---------------+--------+-----+| 500000 | format-500000 | 500000 | 38 |+--------+---------------+--------+-----+1 row in set (0.47 sec)

explain一下這條語句:

123456 mysql> explain select * from t_users where name = 'format-500000';+----+-------------+---------+------+---------------+------+---------+------+--------+-------------+| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |+----+-------------+---------+------+---------------+------+---------+------+--------+-------------+| 1 | SIMPLE | t_users | ALL | NULL | NULL | NULL | NULL | 996677 | Using where |+----+-------------+---------+------+---------------+------+---------+------+--------+-------------+

發現查詢了996677條數據,進行了全表的掃描。

我們給name字段加上索引:

1 mysql> create index IDX_FOR_NAME on t_users(name);

再次執行sql語句:

1234567 mysql> select * from t_users where name = 'format-500000';+--------+---------------+--------+-----+| id | name | age | num |+--------+---------------+--------+-----+| 500000 | format-500000 | 500000 | 38 |+--------+---------------+--------+-----+1 row in set (0.00 sec)

explain一下:

1234567 mysql> explain select * from t_users where name = 'format-500000';+----+-------------+---------+------+---------------+--------------+---------+-------+------+-----------------------+| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |+----+-------------+---------+------+---------------+--------------+---------+-------+------+-----------------------+| 1 | SIMPLE | t_users | ref | IDX_FOR_NAME | IDX_FOR_NAME | 767 | const | 1 | Using index condition |+----+-------------+---------+------+---------------+--------------+---------+-------+------+-----------------------+1 row in set (0.00 sec)

只查詢了1條數據,因為我們加了btree索引,可以快速定位到具體的值。

接下來我們查詢num字段:

12345678910 mysql> select * from t_users where num = 66;+--------+---------------+--------+-----+....| 965109 | format-965109 | 965109 | 66 || 965172 | format-965172 | 965172 | 66 || 965182 | format-965182 | 965182 | 66 || 965213 | format-965213 | 965213 | 66 |....+--------+---------------+--------+-----+10029 rows in set (0.30 sec)

由于num字段也是沒有加索引的,查詢的時候也進行全表的掃描,查詢耗時。接下來我們給num字段加上索引。

1 mysql> create index IDX_FOR_NUM on t_users(num);

然后進行查詢:

12345678910 mysql> select * from t_users where num = 5;+--------+---------------+--------+-----+....| 965109 | format-965109 | 965109 | 5 || 965172 | format-965172 | 965172 | 5 || 965182 | format-965182 | 965182 | 5 || 965213 | format-965213 | 965213 | 5 |....+--------+---------------+--------+-----+10029 rows in set (0.04 sec)

explain一下:

123456 mysql> explain select * from t_users where num = 5;+----+-------------+---------+------+---------------+-------------+---------+-------+-------+-------+| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |+----+-------------+---------+------+---------------+-------------+---------+-------+-------+-------+| 1 | SIMPLE | t_users | ref | IDX_FOR_NUM | IDX_FOR_NUM | 8 | const | 206712 | NULL |+----+-------------+---------+------+---------------+-------------+---------+-------+-------+-------+

雖然我們在num字段上加了索引,但是由于num值在這100w條數據中有很多重復的數據,這個時候索引對查詢速度的提高就沒有那么明顯了。

因為不論是hash類型的索引還是btree類型的索引,他們對于重復的數據的查詢并沒有提高多少。相反,由于添加了索引,導致數據寫入性能變差,而查詢性能又沒有增強多少。所以說不能盲目地添加索引。

復合索引

復合索引也叫聯合索引,表示索引建立在多個列上。

我們刪除t_users上的索引,然后創建一個復合索引。

1234 mysql> drop index IDX_FOR_NUM on t_users;mysql> drop index IDX_FOR_NAME on t_users;mysql> create index INDEX_FOR_NAME_AGE on t_users(name, age);

復合索引支持最左原則,也就是說INDEX_FOR_NAME_AGE索引支持name字段的查找,支持name,age字段的查找,但是不支持age,name字段的查找以及age字段的查找。

1234567891011121314151617181920 mysql> explain select * from t_users where name = 'format-100000';+----+-------------+---------+------+--------------------+--------------------+---------+-------+------+-----------------------+| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |+----+-------------+---------+------+--------------------+--------------------+---------+-------+------+-----------------------+| 1 | SIMPLE | t_users | ref | INDEX_FOR_NAME_AGE | INDEX_FOR_NAME_AGE | 767 | const | 1 | Using index condition |+----+-------------+---------+------+--------------------+--------------------+---------+-------+------+-----------------------+mysql> explain select * from t_users where name = 'format-100000' and age = 100000;+----+-------------+---------+------+--------------------+--------------------+---------+-------------+------+-----------------------+| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |+----+-------------+---------+------+--------------------+--------------------+---------+-------------+------+-----------------------+| 1 | SIMPLE | t_users | ref | INDEX_FOR_NAME_AGE | INDEX_FOR_NAME_AGE | 775 | const,const | 1 | Using index condition |+----+-------------+---------+------+--------------------+--------------------+---------+-------------+------+-----------------------+mysql> explain select * from t_users where age = 100000;+----+-------------+---------+------+---------------+------+---------+------+--------+-------------+| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |+----+-------------+---------+------+---------------+------+---------+------+--------+-------------+| 1 | SIMPLE | t_users | ALL | NULL | NULL | NULL | NULL | 996677 | Using where |+----+-------------+---------+------+---------------+------+---------+------+--------+-------------+

使用age,name字段查找:

123456 mysql> explain select * from t_users where age = 100000 and name = 'format-100000';+----+-------------+---------+------+--------------------+--------------------+---------+-------------+------+-----------------------+| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |+----+-------------+---------+------+--------------------+--------------------+---------+-------------+------+-----------------------+| 1 | SIMPLE | t_users | ref | INDEX_FOR_NAME_AGE | INDEX_FOR_NAME_AGE | 775 | const,const | 1 | Using index condition |+----+-------------+---------+------+--------------------+--------------------+---------+-------------+------+-----------------------+

我們發現使用age,name字段的查找使用了復合索引,這是因為MySQL內部有個查詢優化器幫我們進行了優化。

索引的生效

索引創建之后,查詢的過程并不一定會使用索引。整理如下(t_users表中name和num字段都有單獨的索引):

1.當使用索引查詢比全表掃描更慢。比如下面這句sql中num字段的值分布在1-10之間

123456 mysql> explain select * from t_users where num > 1 and num < 8;+----+-------------+----------+------+---------------+------+---------+------+--------+-------------+| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |+----+-------------+----------+------+---------------+------+---------+------+--------+-------------+| 1 | SIMPLE | t_users | ALL | IDX_ON_NUM | NULL | NULL | NULL | 996504 | Using where |+----+-------------+----------+------+---------------+------+---------+------+--------+-------------+

2.使用or進行查詢,并且or左右兩邊的列有不存在索引的列

123456 mysql> explain select * from t_users where name = 'format-4000' or age = 50;+----+-------------+---------+------+---------------+------+---------+------+--------+-------------+| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |+----+-------------+---------+------+---------------+------+---------+------+--------+-------------+| 1 | SIMPLE | t_users | ALL | IDX_FOR_NAME | NULL | NULL | NULL | 996677 | Using where |+----+-------------+---------+------+---------------+------+---------+------+--------+-------------+

or兩邊的列都有索引:

123456 mysql> explain select * from t_users where name = 'format-4000' or num = 50;+----+-------------+----------+-------------+---------------------------------+---------------------------------+---------+------+------+-----------------------------------------------------------+| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |+----+-------------+----------+-------------+---------------------------------+---------------------------------+---------+------+------+-----------------------------------------------------------+| 1 | SIMPLE | t_users | index_merge | IDX_ON_NUM,IDX_FOR_NAME | IDX_FOR_NAME,IDX_ON_NUM | 767,8 | NULL | 2 | Using union(IDX_FOR_NAME,IDX_ON_NUM); Using where |+----+-------------+----------+-------------+---------------------------------+---------------------------------+---------+------+------+-----------------------------------------------------------+

3.使用like,并以 % 開頭

12345678910111213 mysql> explain select * from t_users where name like "%format-200";+----+-------------+---------+------+---------------+------+---------+------+--------+-------------+| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |+----+-------------+---------+------+---------------+------+---------+------+--------+-------------+| 1 | SIMPLE | t_users | ALL | NULL | NULL | NULL | NULL | 996677 | Using where |+----+-------------+---------+------+---------------+------+---------+------+--------+-------------+mysql> explain select * from t_users where name like "%format-200%";+----+-------------+---------+------+---------------+------+---------+------+--------+-------------+| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |+----+-------------+---------+------+---------------+------+---------+------+--------+-------------+| 1 | SIMPLE | t_users | ALL | NULL | NULL | NULL | NULL | 996677 | Using where |+----+-------------+---------+------+---------------+------+---------+------+--------+-------------+

以 % 結尾的查詢會使用索引:

123456 mysql> explain select * from t_users where name like "format-200%";+----+-------------+---------+-------+---------------+--------------+---------+------+------+-----------------------+| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |+----+-------------+---------+-------+---------------+--------------+---------+------+------+-----------------------+| 1 | SIMPLE | t_users | range | IDX_FOR_NAME | IDX_FOR_NAME | 767 | NULL | 1110 | Using index condition |+----+-------------+---------+-------+---------------+--------------+---------+------+------+-----------------------+

4.復合索引

不是復合索引的最左字段(t_users表有(name,age)復合索引)。

123456 mysql> explain select * from t_users where age = 100000;+----+-------------+---------+------+---------------+------+---------+------+--------+-------------+| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |+----+-------------+---------+------+---------------+------+---------+------+--------+-------------+| 1 | SIMPLE | t_users | ALL | NULL | NULL | NULL | NULL | 996677 | Using where |+----+-------------+---------+------+---------------+------+---------+------+--------+-------------+

5.對varchar類型的字段進行查詢的時候,沒有加上引號

12345678910111213 mysql> explain select * from t_users where name = 111;+----+-------------+---------+------+---------------+------+---------+------+--------+-------------+| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |+----+-------------+---------+------+---------------+------+---------+------+--------+-------------+| 1 | SIMPLE | t_users | ALL | IDX_FOR_NAME | NULL | NULL | NULL | 996677 | Using where |+----+-------------+---------+------+---------------+------+---------+------+--------+-------------+mysql> explain select * from t_users where name = "111";+----+-------------+---------+------+---------------+--------------+---------+-------+------+-----------------------+| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |+----+-------------+---------+------+---------------+--------------+---------+-------+------+-----------------------+| 1 | SIMPLE | t_users | ref | IDX_FOR_NAME | IDX_FOR_NAME | 767 | const | 1 | Using index condition |+----+-------------+---------+------+---------------+--------------+---------+-------+------+-----------------------+

hash索引和btree索引的區別

  • hash索引不能使用范圍查詢,只能使用一些比如 “=”, “<>”, “in”查詢。因為hash索引會計算索引列的hash值,計算出后的hash值經過了hash算法與原先的值完全不一樣,只能進行等值的過濾,不能基于范圍的過濾
  • hash索引遇到大量hash值相同的情況下,性能比btree要差
  • hash索引并不一定一次可以定位到數據。因為基于索引列計算出的hash值會有重復,重復的話需要掃描hash表進行比較
  • 由于hash索引中存放的是經過hash計算之后的hash值,而且hash值的大小關系并不一定和hash運算前的鍵值完全一樣,所以數據庫無法利用索引的數據來避免任何排序運算
  • 對于組合索引,hash索引在計算hash值的時候是組合索引鍵合并后再一起計算hash值,而不是單獨計算hash值,所以通過組合索引的前面一個或幾個索引鍵進行查詢的時候,hash索引也無法被利用
  • InnoDB和MyISAM引擎不支持hash索引
  • 本文作者:Format
    原文鏈接: http://fangjian0423.github.io/2017/07/05/mysql-index-summary/

    總結

    以上是生活随笔為你收集整理的MySQL索引知识总结的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 日韩一区二区高清视频 | 长河落日 | 热播之家 | 亚洲精品国产精品国自产网站按摩 | 亚洲激情影院 | 国产一在线 | 国产黄色www | 女仆裸体打屁屁羞羞免费 | 免费a视频在线观看 | 狠狠爱网站| 伊人网站在线观看 | 日本大尺度电影免费观看全集中文版 | 午夜羞羞网站 | 99国产精品久久 | www亚洲视频| 欧美一级黄色大片 | 天天射av| 欧美日本三级 | 国产无遮挡又黄又爽免费网站 | www.我爱av| 白白色2012年最新视频 | 91嫩草入口 | 春闺艳妇(h)高h产乳 | 国产片网址 | 国产亚洲精品成人av在线 | 黄色美女大片 | 人与动物毛片 | 国产丝袜美腿一区二区三区 | 91手机视频在线观看 | 国产三级国产精品 | 无码国产伦一区二区三区视频 | 国产农村av| 奇米狠狠777 | 国产成人精品女人久久久 | 中国女人一级片 | 久久久精品麻豆 | 国产精品情侣自拍 | 国产成人在线播放视频 | 69av在线| 国产精品久久久久久久久久妞妞 | 综合伊人 | 91免费看片网站 | 免费在线激情视频 | 国产精品xxx视频 | 小情侣高清国产在线播放 | 在线观看污污网站 | 91激情视频在线 | av资源导航 | av影院在线观看 | 中文人妻av久久人妻18 | 一区二区亚洲精品 | 欧美性福利 | 中文字幕视频在线观看 | 黄色小视频免费观看 | 国产最新精品视频 | 亚州| 无码人妻aⅴ一区二区三区有奶水 | 日韩区在线 | 99re99| 欧美日韩国产精品 | 国产精品老熟女一区二区 | 日日夜夜免费视频 | 国产剧情在线 | 人人射人人爽 | av黄色免费网站 | 欧美激情视频二区 | 亚洲人成人 | 亚洲欧洲自拍 | 国产精品国产三级国产aⅴ中文 | 亚洲少妇中文字幕 | 调教奶奴 | 夜夜添无码一区二区三区 | 亚洲精品一区二区三区蜜桃久 | 久久精品美乳 | 中文字幕第80页 | 成人a网站 | 日韩中文字幕在线观看 | 成人无遮挡 | 双腿张开被9个男人调教 | av免费黄色| 国产女主播一区二区三区 | 银杏av| 亚洲av综合色区无码一区 | 国产99在线 | 91成人久久| 日韩免费视频 | 国产一区二区三区在线视频观看 | 国产成人自拍视频在线观看 | 裸体裸乳被免费看视频 | 一级黄色免费 | 狠狠操夜夜操 | 久操视频免费在线观看 | 91黄色小网站 | 成人免费观看视频 | 四虎黄色网址 | 国产极品91 | 日韩欧美成人免费视频 | 国产欧美又粗又猛又爽 | 国产福利在线视频 |