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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

explain ref_你必须要掌握的MySQL命令:explain

發(fā)布時間:2025/3/20 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 explain ref_你必须要掌握的MySQL命令:explain 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

mysql中的explain命令可以用來查看sql語句是否使用了索引,用了什么索引,有沒有做全表掃描??梢詭椭覀儍?yōu)化查詢語句。

explain出來的信息有10列,文章主要介紹type、key、Extra這幾個字段。

演示中涉及到的表結(jié)構(gòu)如下:

CREATE TABLE `dept_desc` (`dept_no` char(4) NOT NULL,`dept_name` varchar(40) NOT NULL,`desc` varchar(255) NOT NULL,PRIMARY KEY (`dept_no`) ) ENGINE=InnoDBCREATE TABLE `dept_emp` (`emp_no` int(11) NOT NULL,`dept_no` char(4) NOT NULL,`from_date` date NOT NULL,`to_date` date NOT NULL,PRIMARY KEY (`emp_no`,`dept_no`),KEY `dept_no` (`dept_no`),CONSTRAINT `dept_emp_ibfk_1` FOREIGN KEY (`emp_no`) REFERENCES `employees` (`emp_no`) ON DELETE CASCADE,CONSTRAINT `dept_emp_ibfk_2` FOREIGN KEY (`dept_no`) REFERENCES `departments` (`dept_no`) ON DELETE CASCADE ) ENGINE=InnoDBCREATE TABLE `employees` (`emp_no` int(11) NOT NULL,`birth_date` date NOT NULL,`first_name` varchar(14) NOT NULL,`last_name` varchar(16) NOT NULL,`gender` enum('M','F') NOT NULL,`hire_date` date NOT NULL,PRIMARY KEY (`emp_no`) ) ENGINE=InnoDB上面的表都是mysql中測試庫的表,需要的同學(xué)可以自行去下載。
官方文檔:https://dev.mysql.com/doc/emp...;
github下載地址:https://github.com/datacharme..._db.git

# key

sql語句實(shí)際執(zhí)行時使用的索引列,有時候mysql可能會選擇優(yōu)化效果不是最好的索引,這時,我們可以在select語句中使用force index(INDEXNAME)來強(qiáng)制mysql使用指定索引或使用ignore index(INDEXNAME)強(qiáng)制mysql忽略指定索引

# type

訪問類型,表示數(shù)據(jù)庫引擎查找表的方式,常見的type類型有:

all,index,range,ref,eq_ref,const。

  • all

全表掃描,表示sql語句會把表中所有表數(shù)據(jù)全部讀取讀取掃描一遍。效率最低,我們應(yīng)盡量避免。

mysql> explain select * from dept_emp; +----+-------------+----------+------+---------------+------+---------+------+--------+-------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+----------+------+---------------+------+---------+------+--------+-------+ | 1 | SIMPLE | dept_emp | ALL | NULL | NULL | NULL | NULL | 331570 | NULL | +----+-------------+----------+------+---------------+------+---------+------+--------+-------+
  • index

全索引掃描,表示sql語句將會把整顆二級索引樹全部讀取掃描一遍,因?yàn)槎壦饕?/p>

樹的數(shù)據(jù)量比全表數(shù)據(jù)量小,所以效率比all高一些。一般查詢語句中查詢字段為索

引字段,且無where子句時,type會為index。如下,mysql確定使用dept_no這

個索引,然后掃描整個dept_no索引樹得到結(jié)果。

mysql> explain select dept_no from dept_emp; +----+-------------+----------+-------+---------------+---------+---------+------+--------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+----------+-------+---------------+---------+---------+------+--------+-------------+ | 1 | SIMPLE | dept_emp | index | NULL | dept_no | 4 | NULL | 331570 | Using index | +----+-------------+----------+-------+---------------+---------+---------+------+--------+-------------+
  • range

部分索引掃描,當(dāng)查詢?yōu)閰^(qū)間查詢,且查詢字段為索引字段時,這時會根據(jù)where條件對索引進(jìn)行部分掃描。

mysql> explain select * from dept_emp where emp_no > '7'; +----+-------------+----------+-------+---------------+---------+---------+------+--------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+----------+-------+---------------+---------+---------+------+--------+-------------+ | 1 | SIMPLE | dept_emp | range | PRIMARY | PRIMARY | 4 | NULL | 165785 | Using where | +----+-------------+----------+-------+---------------+---------+---------+------+--------+-------------+
  • ref

出現(xiàn)于where操作符為‘=’,且where字段為非唯一索引的單表查詢或聯(lián)表查詢。

// 單表 mysql> explain select * from dept_emp where dept_no = 'd005'; +----+-------------+----------+------+---------------+---------+---------+-------+--------+-----------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+----------+------+---------------+---------+---------+-------+--------+-----------------------+ | 1 | SIMPLE | dept_emp | ref | dept_no | dept_no | 4 | const | 145708 | Using index condition | +----+-------------+----------+------+---------------+---------+---------+-------+--------+-----------------------+// 聯(lián)表 mysql> explain select * from dept_emp,departments where dept_emp.dept_no = departments.dept_no; +----+-------------+-------------+-------+---------------+-----------+---------+-------------------------------+------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------------+-------+---------------+-----------+---------+-------------------------------+------+-------------+ | 1 | SIMPLE | departments | index | PRIMARY | dept_name | 42 | NULL | 9 | Using index | | 1 | SIMPLE | dept_emp | ref | dept_no | dept_no | 4 | employees.departments.dept_no | 1 | NULL | +----+-------------+-------------+-------+---------------+-----------+---------+-------------------------------+------+-------------+
  • eq_ref

出現(xiàn)于where操作符為‘=’,且where字段為唯一索引的聯(lián)表查詢。

mysql> explain select * from departments,dept_desc where departments.dept_name=dept_desc.dept_name; +----+-------------+-------------+--------+---------------+-----------+---------+-------------------------------+------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------------+--------+---------------+-----------+---------+-------------------------------+------+-------------+ | 1 | SIMPLE | dept_desc | ALL | NULL | NULL | NULL | NULL | 1 | NULL | | 1 | SIMPLE | departments | eq_ref | dept_name | dept_name | 42 | employees.dept_desc.dept_name | 1 | Using index | +----+-------------+-------------+--------+---------------+-----------+---------+-------------------------------+------+-------------+
  • const

出現(xiàn)于where操作符為‘=’,且where字段為唯一索引的單表查詢,此時最多只會匹配到一行。

mysql> explain select * from departments where dept_no = 'd005'; +----+-------------+-------------+-------+---------------+---------+---------+-------+------+-------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------------+-------+---------------+---------+---------+-------+------+-------+ | 1 | SIMPLE | departments | const | PRIMARY | PRIMARY | 4 | const | 1 | NULL | +----+-------------+-------------+-------+---------------+---------+---------+-------+------+-------+

綜上,單從type字段考慮效率,const > eq_ref > ref > range > index > all.

注意:我們不能僅僅根據(jù)type去判斷兩條sql的執(zhí)行速度。例如type為range的查詢不一定比type為index的全表查詢速度要快,還要看具體的sql。因?yàn)閠ype為index時,查詢是不需要回表操作的,而type為range時,有可能需要回表操作。如sqlA("select dept_no from dept_emp;")和sqlB("select from_date from dept_emp where dept_no > 'd005';"),這個時候sqlB根據(jù)where條件掃描索引樹后,需要回表查詢相應(yīng)的行數(shù)據(jù),以獲取from_date的值,而sqlA雖然掃描了整顆索引樹,但并不需要回表,所以速度可能會比sqlB更快。

# Extra

extra列會包含一些十分重要的信息,我們可以根據(jù)這些信息進(jìn)行sql優(yōu)化

using index: sql語句沒有where查詢條件,使用覆蓋索引,不需要回表查詢即可拿到結(jié)果

using where: 沒有使用索引/使用了索引但需要回表查詢且沒有使用到下推索引

using index && useing where: sql語句有where查詢條件,且使用覆蓋索引,不需要回表查詢即可拿到結(jié)果。

Using index condition:使用索引查詢,sql語句的where子句查詢條件字段均為同一索引字段,且開啟索引下推功能,需要回表查詢即可拿到結(jié)果。

Using index condition && using where:使用索引查詢,sql語句的where子句查詢條件字段存在非同一索引字段,且開啟索引下推功能,需要回表查詢即可拿到結(jié)果。

using filesort: 當(dāng)語句中存在order by時,且orderby字段不是索引,這個時候mysql無法利用索引進(jìn)行排序,只能用排序算法重新進(jìn)行排序,會額外消耗資源。

Using temporary:建立了臨時表來保存中間結(jié)果,查詢完成之后又要把臨時表刪除。會很影響性能,需盡快優(yōu)化。

有時在extra字段中會出現(xiàn)"Impossible WHERE noticed after reading const tables"這種描述。翻看網(wǎng)上資料后,個人發(fā)現(xiàn)這是mysql一種很怪的處理方式。

當(dāng)sql語句滿足:

1、根據(jù)主鍵查詢或者唯一性索引查詢;

2、where操作符為"="時。

在sql語句優(yōu)化階段,mysql會先根據(jù)查詢條件找到相關(guān)記錄,這樣,如果這條數(shù)據(jù)不存在,實(shí)際上就進(jìn)行了一次全掃描,然后得出一個結(jié)論,該數(shù)據(jù)不在表中。這樣對于并發(fā)較高的數(shù)據(jù)庫,會加大負(fù)載。所以,如果數(shù)據(jù)不用唯一的話,普通的索引比唯一索引更好用。

作者:Mr林_月生 來源:https://www.jianshu.com/p/8cc...
  • 升職加薪必備!運(yùn)維工程師打怪升級進(jìn)階成神之路
  • 我沒有開掛的人生!自律和堅持,是我走IT之路的唯一捷徑
  • 全網(wǎng)最新、最全Linux面試題(2020版)!
  • 史上最全、最新的Redis面試題(2020最新版)!
  • 贊!7000 字學(xué)習(xí)筆記,MySQL 從入門到放棄

如有錯誤或其它問題,歡迎小伙伴留言評論、指正。如有幫助,歡迎點(diǎn)贊+轉(zhuǎn)發(fā)分享。

更多相關(guān)開源技術(shù)文章,請持續(xù)關(guān)注民工哥知乎技術(shù)專欄。

我是民工哥,一個愛折騰的IT技術(shù)老司機(jī),歡迎關(guān)注我,我們一起學(xué)習(xí),共同成長!!

總結(jié)

以上是生活随笔為你收集整理的explain ref_你必须要掌握的MySQL命令:explain的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。