MySQL執行計劃extra中的using index 和 using where using index 的區別

来源:http://www.cnblogs.com/wy123/archive/2017/08/15/7366486.html
-Advertisement-
Play Games

本文出處:http://www.cnblogs.com/wy123/p/7366486.html (保留出處並非什麼原創作品權利,本人拙作還遠遠達不到,僅僅是為了鏈接到原文,因為後續對可能存在的一些錯誤進行修正或補充,無他) mysql執行計劃中的extra列中表明瞭執行計劃的每一步中的實現細節,其 ...


 

本文出處:http://www.cnblogs.com/wy123/p/7366486.html 
(保留出處並非什麼原創作品權利,本人拙作還遠遠達不到,僅僅是為了鏈接到原文,因為後續對可能存在的一些錯誤進行修正或補充,無他)

 

mysql執行計劃中的extra列中表明瞭執行計劃的每一步中的實現細節,其中包含了與索引相關的一些細節信息
其中跟索引有關的using index 在不同的情況下會出現Using index, Using where Using index ,Using index condition等
那麼Using index 和 Using where;Using index 有什麼區別?網上搜了一大把文章,說實在話也沒怎麼弄懂,於是就自己動手試試。


本文僅從最簡單的單表去測試using index 和 using where using index以及簡單測試using index condition的情況的出現時機 。
執行計劃的生成與表結構,表數據量,索引結構,統計信息等等上下文等多種環境有關,無法一概而論,複雜情況另論。

 

測試環境搭建

  測試表以及測試數據搭建,類似於訂單表和訂單明細表,暫時先用訂單表做測試

  測試表結構

create table test_order
(
    id int auto_increment primary key,
    user_id int,
    order_id int,
    order_status tinyint,
    create_date datetime
);

create table test_orderdetail ( id int auto_increment primary key, order_id int, product_name varchar(100), cnt int, create_date datetime ); create index idx_userid_order_id_createdate on test_order(user_id,order_id,create_date); create index idx_orderid_productname on test_orderdetail(order_id,product_name);

測試數據(50W)

CREATE DEFINER=`root`@`%` PROCEDURE `test_insertdata`(IN `loopcount` INT)
    LANGUAGE SQL
    NOT DETERMINISTIC
    CONTAINS SQL
    SQL SECURITY DEFINER
    COMMENT ''
BEGIN
    declare v_uuid  varchar(50);
    while loopcount>0 do
        set v_uuid = uuid();
        insert into test_order (user_id,order_id,order_status,create_date) values (rand()*1000,id,rand()*10,DATE_ADD(NOW(), INTERVAL - RAND()*20000 HOUR));
        insert into test_orderdetail(order_id,product_name,cnt,create_date) values (rand()*100000,v_uuid,rand()*10,DATE_ADD(NOW(), INTERVAL - RAND()*20000 HOUR));
        set loopcount = loopcount -1;
    end while;
END

 

Using index VS Using where Using index

  首先,在"訂單表"上,這裡是一個多列複合索引
  create index idx_userid_order_id_createdate on test_order(user_id,order_id,create_date);

 

Using index 

1,查詢的列被索引覆蓋,並且where篩選條件是索引的是前導列,Extra中為Using index

 

Using where Using index

  1,查詢的列被索引覆蓋,並且where篩選條件是索引列之一但是不是索引的不是前導列,Extra中為Using where; Using index,意味著無法直接通過索引查找來查詢到符合條件的數據

2,查詢的列被索引覆蓋,並且where篩選條件是索引列前導列的一個範圍,同樣意味著無法直接通過索引查找查詢到符合條件的數據

   

NULL(既沒有Using index,也沒有Using where Using index,也沒有using where

  1,查詢的列未被索引覆蓋,並且where篩選條件是索引的前導列,
       意味著用到了索引,但是部分欄位未被索引覆蓋,必須通過“回表”來實現,不是純粹地用到了索引,也不是完全沒用到索引,Extra中為NULL(沒有信息)

 

Using where

  1,查詢的列未被索引覆蓋,where篩選條件非索引的前導列,Extra中為Using where

  2,查詢的列未被索引覆蓋,where篩選條件非索引列,Extra中為Using where

   

  using where 意味著通過索引或者表掃描的方式進程where條件的過濾,
  反過來說,也就是沒有可用的索引查找,當然這裡也要考慮索引掃描+回表與表掃描的代價。
  這裡的type都是all,說明MySQL認為全表掃描是一種比較低的代價。

 Using index condition

  1,-- 查詢的列不全在索引中,where條件中是一個前導列的範圍

  

  2,查詢列不完全被索引覆蓋,查詢條件完全可以使用到索引(進行索引查找)

  

  參考:MySQL · 特性分析 · Index Condition Pushdown (ICP)

  多表關聯的時候Using index condition出現的情況更多,目前還不怎麼理解Using index condition的內部實現模式。

 

結論:
  1,Extra中的為Using index的情況
    where篩選列是索引的前導列 &&查詢列被索引覆蓋 && where篩選條件是一個基於索引前導列的查詢,意味著通過索引超找就能直接找到符合條件的數據,並且無須回表

  2,Extra中的為空的情況
    查詢列存在未被索引覆蓋&&where篩選列是索引的前導列,意味著通過索引超找並且通過“回表”來找到未被索引覆蓋的欄位,

3,Extra中的為Using where Using index:
  出現Using where Using index意味著是通過索引掃描(或者表掃描)來實現sql語句執行的,即便是索引前導列的索引範圍查找也有一點範圍掃描的動作,不管是前非索引前導列引起的,還是非索引列查詢引起的。

 

尚未解決的問題:

     查詢1

查詢2

    查詢3(邏輯上等價於查詢1+查詢2),執行計劃發生了很大的變化。

 

總結:

  MySQL執行計劃中的Extra中信息非常多,不僅僅包括Using index,Using where Using index,Using index condition,Using where,尤其是在多表連接的時候,這一點在相對MSSQL來說,不夠直觀或者結構化。
  MSSQL中是通過區分索引查找(index seek),索引掃描(index scan),表掃描(table scan)來實現具體的查詢的,這圖形化的執行計劃在不同的場景下是非常直觀的,要想完全弄懂MySQL的這個執行計劃,可能要更多地在實踐中摸索。

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 討人喜歡的 MySQL replace into 用法(insert into 的增強版) 在向表中插入數據的時候,經常遇到這樣的情況:1. 首先判斷數據是否存在; 2. 如果不存在,則插入;3.如果存在,則更新。 在 SQL Server 中可以這樣處理: if not exists (selec ...
  • - 在芝加哥工作的人中,誰的工資最高select * from(select e.ename from emp e join dept d on(e.deptno = d.deptno)where d.loc='CHICAGO' order by sal desc) where rownum=1; ...
  • MySQL Database on Azure 是 Azure 平臺上推出的 MySQL 雲資料庫服務,通過全面相容 MySQL 協議,為用戶提供了一個全托管的性能穩定、可快速部署、高可用、高安全性的資料庫服務。客戶可以使用常見的支持 MySQL 的平臺與技術進行開發與集成。本文演示瞭如何使用 My ...
  • 事務用於處理數據的一致性,事務的定義是,處於同一個事務中的操作是一個工作單元,要麼全部執行成功,要麼全部執行失敗。把事務的概念應用到在實際的SSIS Package場景中,如何在Package中實現事務,事務的行為是什麼樣的,你真的瞭解嗎? SSIS預設支持Task組件級別的事務,在預設情況下,單個 ...
  • 如果轉載,請註明博文來源: www.cnblogs.com/xinysu/ ,版權歸 博客園 蘇家小蘿蔔 所有。望各位支持! 少年入門筆記,整理出來一起入坑!入門的視屏來自imooc的:http://www.imooc.com/learn/839 如果轉載,請註明博文來源: www.cnblogs. ...
  • 打開網址可以看到這是一個類似chm格式但可以線上瀏覽的參考手冊,非常的完美,該手冊詳細講解了:如何安裝mysql,MySQL管理器,查詢瀏覽器,移植工具包,以及sql語句語法,優化,函數和操作符,存儲引擎和表類型等等內容,是學習mysq必備的參考手冊,能夠讓廣大網友們更好更輕鬆的掌握mysql資料庫... ...
  • EF對於已有資料庫的Code First支持 原文鏈接 本文將逐步介紹怎樣用Code First的方式基於已有資料庫進行開發。Code First支持你使用C#或者VB.Net定義類.並使用數據模型標識和Fluent API定義與配置模型。 前提 已經安裝 Visual Studio 2012 或者 ...
  • 嵌套查詢 一個SELECT FROM WHERE語句稱為一個查詢塊。 嵌套查詢:將一個查詢塊嵌套在另一個查詢塊的WHERE子句或者HAVING短語的條件中的查詢。 註:子查詢的SELECT語句中不能使用ORDER BY子句,ORDER BY子句只能對最終查詢結果排序。 1.帶有IN謂詞的子查詢: 子 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...