日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

MySQL索引失效和EXPLAIN工具:你建立的索引真的起到作用了嗎?

 

在我們使用MySQL的過程中,隨著數據量越來越大,查詢顯得有些吃力,這時候就要針對查詢就行優化,針對查詢優化,通過給字段添加索引可以提高數據的讀取速度,提高項目的并發能力和抗壓能力。在上一篇我們講了給數據庫中的表添加索引,來提高它的查詢速度,但是會有另外一種情況出現,那就是我們給表中字段加了索引,但是查詢的時候依舊很慢,沒有什么變化,這時就是因為建立的索引失效了,今天就來講一講索引失效的情況!

對于查看索引是否失效,MySQL數據庫針對每一條SQL語句,提供了一個查看它的執行計劃的工具,叫做EXPLAIN,咱們先來了解一下這個工具。首先說一下接下來用到的表,創建的表結構為:

CREATE TABLE `tb_user` (
 `id` BIGINT (20),
 `user_name` VARCHAR (200),
 `user_password` VARCHAR (200),
 `birth` DATETIME ,
 `sex` CHAR (4),
				 `age` int(8),
 `email` VARCHAR (200),
 `mobile` VARCHAR (200),
 `create_date` DATETIME ,
 `update_date` DATETIME ,
 `description` VARCHAR (800)
) ENGINE=INNODB;

創建一個存儲函數,向里面插入一百萬條數據:

DELIMITER $$
CREATE
 PROCEDURE insert_tb_user()
 BEGIN
 DECLARE i INT;
 SET i=0;
 WHILE i>=0 && i<= 1000000 DO
 INSERT INTO tb_user
 (`id`, `user_name`, `user_password`, `birth`, `sex`, `age`, `email`, `mobile`, `create_date`, `update_date`, `description`) VALUES
 (i,concat('admin',i),concat('admin',i),NOW(),'M',i,'[email protected]',concat('12345',i),NOW(),NOW(),concat('超級管理員',i));
 SET i=i + 1;
 END WHILE;
 
 END$$
DELIMITER ;
-- 執行存儲函數
call insert_tb_user()

生成的表數據如下:

MySQL索引失效和EXPLAIN工具:你建立的索引真的起到作用了嗎?

 

利用這個表,我們來介紹一下執行計劃和索引失效的情況。

首先來看一下執行計劃的結果是什么樣的,執行計劃的查看,就是在查詢語句的前面加上EXPLAIN關鍵字就可以了:

MySQL索引失效和EXPLAIN工具:你建立的索引真的起到作用了嗎?

 

對于這些字段的意思,咱們一一來解釋:

一、 id,SELECT識別符。

*id相同時,執行順序由上至下

*如果是子查詢,id的序號會遞增,id值越大優先級越高,越先被執行

二、select_type,查詢中每個select子句的類型

*SIMPLE(簡單SELECT,不使用UNION或子查詢等)

*PRIMARY(子查詢中最外層查詢)

*UNION(UNION中的第二個或后面的SELECT語句)

*DEPENDENT UNION(UNION中的第二個或后面的SELECT語句)

*UNION RESULT(UNION的結果,union語句中第二個select開始后面所有select)

*SUBQUERY(子查詢中的第一個SELECT,結果不依賴于外部查詢)

*DEPENDENT SUBQUERY(子查詢中的第一個SELECT,依賴于外部查詢)

* DERIVED(派生表的SELECT, FROM子句的子查詢)

* UNCACHEABLE SUBQUERY(一個子查詢的結果不能被緩存,必須重新評估外鏈接的第一行)

三、 table,顯示這一步所訪問數據庫中表名稱。

四、type,對表訪問方式

*all:Full Table Scan, MySQL將遍歷全表以找到匹配的行

*index: Full Index Scan,index與ALL區別為index類型只遍歷索引樹

*range:只檢索給定范圍的行,使用一個索引來選擇行

*ref: 表示上述表的連接匹配條件,即哪些列或常量被用于查找索引列上的值

*eq_ref: 類似ref,區別就在使用的索引是唯一索引,對于每個索引鍵值,表中只有一條記錄匹配,簡單來說,就是多表連接中使用primary key或者 unique key作為關聯條件

*const、system: 當MySQL對查詢某部分進行優化,并轉換為一個常量時,使用這些類型訪問。如將主鍵置于where列表中,MySQL就能將該查詢轉換為一個常量,system是const類型的特例,當查詢的表只有一行的情況下,使用system

*NULL: MySQL在優化過程中分解語句,執行時甚至不用訪問表或索引,例如從一個索引列里選取最小值可以通過單獨索引查找完成。

五、 possible_keys,可能使用的索引。

六、key,實際使用的索引

七、key_len,索引中使用的字節數,可通過該列計算查詢中使用的索引的長度

八、ref,列與索引的比較,表示上述表的連接匹配條件

九、rows,估算出結果集行數

十、Extra,MySQL解決查詢的詳細信息

*Using where:不用讀取表中所有信息,僅通過索引就可以獲取所需數據

*Using temporary:表示MySQL需要使用臨時表來存儲結果集,group by ; order by

*Using filesort:包含 order by ,而且無法利用索引完成的排序操作稱為“文件排序”

*Using join buffer:該值強調了在獲取連接條件時沒有使用索引,并且需要連接緩沖區來存儲中間結果。

*Impossible where:這個值強調了where語句會導致沒有符合條件的行。

*Select tables optimized away:這個值意味著僅通過使用索引,優化器可能僅從聚合函數結果中返回一行

*No tables used:Query語句中使用from dual 或不含任何from子句

以上就是對EXPLAIN工具的一個介紹,了解了這個工具后,我們結合這個執行工具,來看一看哪些情況會導致這個索引失效!

第一種情況:針對聯合索引,是否遵循最左匹配原則;

我們user_name,user_password,mobile建立一個聯合索引,如下:

MySQL索引失效和EXPLAIN工具:你建立的索引真的起到作用了嗎?

 

聯合索引其實是建立了三個索引,也就是user_name的索引,user_name,user_password的索引,user_name,user_password,mobile的索引,最左匹配原則的意思,是否在語句中使用了最左建立的索引,也就是user_name的索引,演示一下:

MySQL索引失效和EXPLAIN工具:你建立的索引真的起到作用了嗎?

 

當我們把user_name的查詢條件去掉之后,會是什么情況呢?

MySQL索引失效和EXPLAIN工具:你建立的索引真的起到作用了嗎?

 

我們會看到索引已經失效了,用的是全表掃描,違背了最左匹配的原則,那么對于查詢語句select * from tb_user where user_password='admin66666' and user_name='admin66666' and mobile='1234566666'會用到索引嗎?答案如下:

MySQL索引失效和EXPLAIN工具:你建立的索引真的起到作用了嗎?

 

也是用到了聯合索引,這和你條件中寫的順序是沒有關系的!

第二種情況:在索引列上做了函數操作,會導致索引失效而導致全表掃描

我們先把那個聯合索引刪除掉,然后在user_name這一列上建立一個唯一索引:

MySQL索引失效和EXPLAIN工具:你建立的索引真的起到作用了嗎?

 


MySQL索引失效和EXPLAIN工具:你建立的索引真的起到作用了嗎?

 


MySQL索引失效和EXPLAIN工具:你建立的索引真的起到作用了嗎?

 

先不在索引列上做函數操作,執行計劃如下:

MySQL索引失效和EXPLAIN工具:你建立的索引真的起到作用了嗎?

 

很顯然使用了索引,那么索引列進行函數操作呢?例如做一個字符拼接的操作:

MySQL索引失效和EXPLAIN工具:你建立的索引真的起到作用了嗎?

 

第三種情況:語句中like查詢是以%開頭,索引會失效變成全表掃描,覆蓋索引。

示例如下:

MySQL索引失效和EXPLAIN工具:你建立的索引真的起到作用了嗎?

 

如果模糊查詢不是以%開頭的,那么也是可以用到索引的:

MySQL索引失效和EXPLAIN工具:你建立的索引真的起到作用了嗎?

 

第四種情況:使用is not null 會導致無法使用索引

示例如下:

MySQL索引失效和EXPLAIN工具:你建立的索引真的起到作用了嗎?

 

第五種情況:查詢語句中,如果條件中有or,即使其中有條件帶索引也不會使用。要想使用or,又想讓索引生效,只能將or條件中的每個列都加上索引

MySQL索引失效和EXPLAIN工具:你建立的索引真的起到作用了嗎?

 

上面的sql語句是可以用到索引的,當我們把and換成or時,就會變成全表掃描:

MySQL索引失效和EXPLAIN工具:你建立的索引真的起到作用了嗎?

 

這時我們對mobile也加上索引,這條sql語句也就會使用上索引:

MySQL索引失效和EXPLAIN工具:你建立的索引真的起到作用了嗎?

 


MySQL索引失效和EXPLAIN工具:你建立的索引真的起到作用了嗎?

 

第六種情況:使用不等于(!= 或者<>)的時候,無法使用索引,會導致索引失效

第七種情況:不能使用索引中范圍條件右邊的列,范圍之后索引失效。(< ,> between and)

這些情況就不在進行實際操作了,感興趣的朋友可以動手操作一下,也許隨著MySQL版本的更新迭代,對這些查詢語句進行內部優化,一些索引失效的情況就會消失。除了以上這些情況會導致索引失效,還有哪些情況會導致索引失效呢?

分享到:
標簽:索引 MySQL
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定