自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

分析SQL執(zhí)行計(jì)劃,需要關(guān)注哪些重要信息

數(shù)據(jù)庫 其他數(shù)據(jù)庫
type = index,key = idx_abc,extra = 使用 where;使用 index。這表明查詢利用了 idx_abc 的聯(lián)合索引,但未嚴(yán)格遵守最左前綴匹配,或者雖然遵守了最左前綴,但在 a 字段上進(jìn)行了范圍查詢。因此,實(shí)際上仍需掃描索引樹,效率并不理想。

下面是一次 explain 返回的一條 SQL 語句的執(zhí)行計(jì)劃的內(nèi)容:

+----+-------------+-------+------------+-------+---------------+----------+---------+------+------+----------+--------------------------+
| id | select_type | table | partitions | type  | possible_keys | key      | key_len | ref  | rows | filtered | Extra                    |
+----+-------------+-------+------------+-------+---------------+----------+---------+------+------+----------+--------------------------+
|  1 | SIMPLE      | t2    | NULL       | index | NULL          | idx_abc | 198     | NULL |    5 |    20.00 | Using where; Using index |
+----+-------------+-------+------------+-------+---------------+----------+---------+------+------+----------+--------------------------+

一個(gè)執(zhí)行計(jì)劃中,共有 12 個(gè)字段,每個(gè)字段都十分重要。簡單介紹這 12 個(gè)字段:

  1. id:執(zhí)行計(jì)劃中每個(gè)操作的獨(dú)特標(biāo)識(shí)符。對于一條查詢語句,每個(gè)操作都有其唯一的 id。然而,在多表連接時(shí),一次解釋中的多個(gè)記錄可能具有相同的 id。
  2. select_type:操作的種類。常見種類包括 SIMPLE、PRIMARY、SUBQUERY、UNION 等。不同種類的操作會(huì)影響查詢的執(zhí)行效率。
  3. table:當(dāng)前操作所涉及的表。
  4. partitions:當(dāng)前操作所涉及的分區(qū)。
  5. type:表示查詢時(shí)所使用的索引類型,包括 ALL、index、range、ref、eq_ref、const 等。
  6. possible_keys:表示可能被查詢優(yōu)化器選擇使用的索引。
  7. key:表示查詢優(yōu)化器選擇使用的索引。
  8. key_len:表示索引的長度。索引的長度越短,查詢時(shí)的效率越高。
  9. ref:用來表示哪些列或常量被用來與 key 列中命名的索引進(jìn)行比較。
  10. rows:表示此操作需要掃描的行數(shù),即掃描表中多少行才能得到結(jié)果。
  11. filtered:表示此操作過濾掉的行數(shù)占掃描行數(shù)的百分比。該值越大,表示查詢結(jié)果越準(zhǔn)確。
  12. Extra:表示其他額外的信息,包括 Using index、Using filesort、Using temporary 等。

假如我們有如下一張表(MySQL Innodb 5.7):

CREATE TABLE `t2` (
  `id` INT(11),
  `a` varchar(64) NOT NULL,
  `b` varchar(64) NOT NULL,
  `c` varchar(64) NOT NULL,
  `d` varchar(64) NOT NULL,
  `f` varchar(64) DEFAULT NULL,
  PRIMARY KEY(id),
  UNIQUE KEY `f` (`f`),
  KEY `idx_abc` (`a`,`b`,`c`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1

首先,我們來分析幾個(gè)重要字段的不同取值及其區(qū)別:

對于type字段,不同取值對查詢性能有顯著影響:

  • system:表示系統(tǒng)表,數(shù)據(jù)量較小,通常不需要進(jìn)行磁盤 IO。
  • const:使用常數(shù)索引,MySQL 在查詢時(shí)只會(huì)使用常數(shù)值進(jìn)行匹配。比如:
explain select * from t2 where f='Paidaxing';
  • 此時(shí)使用了唯一性索引進(jìn)行唯一查詢。
  • eq_ref:唯一索引掃描,只會(huì)掃描索引樹中的一個(gè)匹配行。比如:
explain select * from t1 join t2 on t1.id = t2.id where t1.f = 'P';
  • 當(dāng)連接操作中使用了唯一索引或主鍵索引,并且連接條件是基于這些索引的等值條件時(shí),MySQL 通常會(huì)選擇 eq_ref 連接類型,以提高查詢性能。
  • ref:非唯一索引掃描,只會(huì)掃描索引樹中的一部分來查找匹配的行。比如:
explain select * from t2 where a = 'Paidaxing';
  • 此時(shí)使用了非唯一索引進(jìn)行查詢。
  • range:范圍掃描,只會(huì)掃描索引樹中的一個(gè)范圍來查找匹配的行。比如:
explain select * from t2 where a > 'a' and a < 'c';
  • 此時(shí)使用了索引進(jìn)行性范圍查詢。
  • index:全索引掃描,會(huì)遍歷索引樹來查找匹配的行。比如:
explain select c from t2 where b = 'P';
  • 這里的 index 表示做了索引樹掃描,效率并不高,不符合最左前綴匹配的查詢。
  • ALL:全表掃描,將遍歷全表來找到匹配的行。比如:
explain select * from t2 where d = "ni";
  • 此時(shí)使用了非索引字段進(jìn)行查詢。

需要注意的是,以上類型由快到慢排列為:system > const > eq_ref > ref > range > index > ALL。

接下來我們來探討兩個(gè)常被忽略但十分重要的字段:

possible_keys 和 key 字段:

  • possible_keys(可能的索引):這一字段表示查詢語句中可能可以利用的索引,但并不一定實(shí)際使用這些索引。possible_keys 列出了所有可能用于查詢的索引,包括聯(lián)合索引的組合。
  • key(使用的索引):相對應(yīng)地,key 字段表示實(shí)際被查詢所使用的索引。如果在查詢中使用了索引,則該字段將顯示使用的索引名稱。它是實(shí)際用于查詢的索引。

接著說一個(gè)很重要!的字段,但是經(jīng)常被忽略的字段 extra,這個(gè)字段描述了 MySQL 在執(zhí)行查詢時(shí)所做的一些附加操作。下面是 Extra 可能的取值及其含義:

extra 字段:

  • Using where(使用 where):這表示 MySQL 在檢索行后會(huì)再次進(jìn)行條件過濾,使用 WHERE 子句進(jìn)行進(jìn)一步的篩選。這可能出現(xiàn)在列未被索引覆蓋,或者 where 篩選條件涉及非索引的前導(dǎo)列或非索引列。
explain select * from t2 where d = "ni";   # 非索引字段查詢
explain select d from t2 where b = "ni"; # 未索引覆蓋,用聯(lián)合索引的非前導(dǎo)列查詢
  • Using index(使用索引):MySQL 使用了覆蓋索引來優(yōu)化查詢,只需掃描索引而無需回到數(shù)據(jù)表中檢索行。
explain select b,c from t2 where a = "ni";  # 索引覆蓋
  • Using index condition(使用索引條件):表示查詢在索引上執(zhí)行了部分條件過濾,通常與索引下推有關(guān)。
explain select d from t2 where a = "ni" and b like "s%";   # 使用到索引下推。
  • Using where; Using index(使用 where;使用索引):查詢的列被索引覆蓋,且 where 篩選條件是索引列之一,但不是索引的前導(dǎo)列,或者 where 篩選條件是索引列前導(dǎo)列的一個(gè)范圍。
explain select a from t2 where b = "ni";   # 索引覆蓋,但是不符合最左前綴
 explain select b from t2 where a in ('a','d','sd');   # 索引覆蓋,但是前導(dǎo)列是個(gè)范圍
  • Using join buffer(使用連接緩存):MySQL 使用了連接緩存。
explain select * from t1 join t2 on t1.id = t2.id where a = 's';
  • Using temporary(使用臨時(shí)表):MySQL 創(chuàng)建了臨時(shí)表來存儲(chǔ)查詢結(jié)果,通常在排序或分組時(shí)發(fā)生。
explain select count(*),b  from t2 group by b;
  • Using filesort(使用文件排序):MySQL 將使用文件排序而不是索引排序,通常發(fā)生在無法使用索引進(jìn)行排序時(shí)。
explain select count(*),b  from t2 group by b;
  • Using index for group-by(使用索引進(jìn)行分組):MySQL 在分組操作中使用了索引。通常發(fā)生在分組操作涉及到索引中的所有列時(shí)。
  • Using filesort for group-by(使用文件排序進(jìn)行分組):MySQL 在分組操作中使用了文件排序。這通常發(fā)生在無法使用索引進(jìn)行分組操作時(shí)。
  • Range checked for each record(為每條記錄檢查范圍):表示 MySQL 在使用索引范圍查找時(shí),需要對每一條記錄進(jìn)行檢查。
  • Using index for order by(使用索引進(jìn)行排序):MySQL 在排序操作中使用了索引。通常發(fā)生在排序涉及到索引中的所有列時(shí)。
  • Using filesort for order by(使用文件排序進(jìn)行排序):MySQL 在排序操作中使用了文件排序。這通常發(fā)生在無法使用索引進(jìn)行排序時(shí)。
  • Using index for group-by; Using index for order by(在分組和排序中使用索引):表示 MySQL 在分組和排序操作中都使用了索引。

課外補(bǔ)充

如何判斷一條 SQL 走沒有索引

首先看 key 字段有沒有值,有值表示用到了索引樹,但是具體是怎么用的,還得看 type 和 extra。

簡單說以下幾個(gè)情況:

情況一:

explain select b from t2 where a in ('a','d','sd');

+----+-------+---------------+----------+--------------------------+
| id | type  | possible_keys | key      | Extra                    |
+----+-------+---------------+----------+--------------------------+
|  1 | index | NULL          | idx_abc | Using where; Using index |
+----+-------+---------------+----------+--------------------------+

type = index,key = idx_abc,extra = 使用 where;使用 index。這表明查詢利用了 idx_abc 的聯(lián)合索引,但未嚴(yán)格遵守最左前綴匹配,或者雖然遵守了最左前綴,但在 a 字段上進(jìn)行了范圍查詢。因此,實(shí)際上仍需掃描索引樹,效率并不理想。

情況二:

explain select * from t2 where a = 'Paidaxing';

+----+-------+---------------+----------+--------------------------+
| id | type  | possible_keys | key      | Extra                    |
+----+-------+---------------+----------+--------------------------+
|  1 | ref   | idx_abc      | idx_abc | NULL                     |
+----+-------+---------------+----------+--------------------------+

表示用到了索引進(jìn)行查詢,并且用到的是 idx_abc 這個(gè)非唯一索引。

情況三:

explain select * from t2 where f = 'f';

+----+-------+---------------+----------+--------------------------+
| id | type  | possible_keys | key      | Extra                    |
+----+-------+---------------+----------+--------------------------+
|  1 | const | f             | f        | NULL                     |
+----+-------+---------------+----------+--------------------------+

表示用到了索引進(jìn)行查詢,并且用到的是 f 這個(gè)唯一索引。

情況四:

explain select b,c from t2 where a = 'Paidaxing';

+----+-------+---------------+----------+--------------------------+
| id | type  | possible_keys | key      | Extra                    |
+----+-------+---------------+----------+--------------------------+
|  1 | ref   | idx_abc      | idx_abc |  Using index             |
+----+-------+---------------+----------+--------------------------+

表示用到了索引進(jìn)行查詢,并且用到了 idx_abc 這個(gè)索引,而且查詢用到了覆蓋索引,不需要回表。

情況五:

explain select b,c from t2 where d = 'Paidaxing';

+----+-------+---------------+----------+--------------------------+
| id | type  | possible_keys | key      | Extra                    |
+----+-------+---------------+----------+--------------------------+
|  1 | ALL   | NULL          | NULL     |  Using where             |
+----+-------+---------------+----------+--------------------------+

表示沒有用到索引。

責(zé)任編輯:武曉燕 來源: 碼上遇見你
相關(guān)推薦

2011-09-14 17:03:17

數(shù)據(jù)庫執(zhí)行計(jì)劃解析

2015-04-22 14:17:45

SQL SERVERMSSQL SERVE緩沖區(qū)

2024-09-12 15:16:14

2010-11-04 14:35:38

DB2 sql文執(zhí)行計(jì)

2009-11-18 17:05:47

捕獲Oracle SQ

2011-08-18 09:19:19

SQL Server的SQL查詢優(yōu)化

2018-02-27 14:00:35

數(shù)據(jù)庫MySQL統(tǒng)計(jì)信息

2014-08-28 09:54:35

SQL Server

2010-11-04 14:25:19

DB2 SQL文執(zhí)行計(jì)

2021-03-17 09:35:51

MySQL數(shù)據(jù)庫explain

2023-09-21 10:55:51

MysqlSQL語句

2021-05-28 10:46:36

MySQL執(zhí)行計(jì)劃

2021-12-13 22:15:29

SQLOracle共享池

2010-08-04 10:10:47

2022-08-08 08:03:44

MySQL數(shù)據(jù)庫CBO

2009-11-13 16:28:02

Oracle生成執(zhí)行計(jì)

2020-12-25 08:52:53

SQLMysql 數(shù)據(jù)庫

2020-02-02 19:53:57

數(shù)據(jù)庫數(shù)據(jù)庫優(yōu)化SQL優(yōu)化

2010-04-16 09:27:18

Ocacle執(zhí)行計(jì)劃

2020-09-15 08:44:57

MySQL慢日志SQL
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)