mysql explain的使用(優化查詢)

来源:http://www.cnblogs.com/0201zcr/archive/2016/09/11/5742382.html
-Advertisement-
Play Games

explain顯示了mysql如何使用索引來處理select語句以及連接表。可以幫助選擇更好的索引和寫出更優化的查詢語句。 1、創建資料庫 創建的sql語句如下: 2、explain使用方法 使用方法:在select語句前加上explain 就可以了,如: 結果: 3、explain各個參數解釋 i ...


  explain顯示了mysql如何使用索引來處理select語句以及連接表。可以幫助選擇更好的索引寫出更優化的查詢語句

1、創建資料庫

  創建的sql語句如下:

/*
 Navicat MySQL Data Transfer

 Source Server         : localhost-newpassword
 Source Server Version : 50550
 Source Host           : localhost
 Source Database       : testExplain

 Target Server Version : 50550
 File Encoding         : utf-8

 Date: 08/05/2016 18:06:12 PM
*/

SET NAMES utf8;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
--  Table structure for `user`
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
  `id` int(11) NOT NULL,
  `name` varchar(30) NOT NULL,
  `age` int(11) NOT NULL,
  `sex` tinyint(4) NOT NULL,
  `isDeleted` tinyint(4) NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `id_unidx` (`id`) USING BTREE,
  UNIQUE KEY `name_unidx` (`name`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

-- ----------------------------
--  Records of `user`
-- ----------------------------
BEGIN;
INSERT INTO `user` VALUES ('1', 'wwwwe', '11', '1', '0'), ('2', '222', '22', '1', '0'), ('3', '2222', '10', '0', '0');
COMMIT;

SET FOREIGN_KEY_CHECKS = 1;

2、explain使用方法

使用方法:在select語句前加上explain 就可以了,如:

explain select * from user where id = 1

 

結果:

+----+-------------+-------+-------+------------------+---------+---------+-------+------+-------+
| id | select_type | table | type  | possible_keys    | key     | key_len | ref   | rows | Extra |
+----+-------------+-------+-------+------------------+---------+---------+-------+------+-------+
| 1  | SIMPLE      | user  | const | PRIMARY,id_unidx | PRIMARY | 4       | const | 1    |       |
+----+-------------+-------+-------+------------------+---------+---------+-------+------+-------+

3、explain各個參數解釋

id:select識別符。這個是select查詢序列號。這個不重要,查詢序號即為sql語句執行的順序。

select_type主要有下麵幾個值:

  • simple 它表示簡單的select,沒有union和子查詢
  • primary 最外面的select,在有子查詢的語句中,最外面的select查詢就是primary
  • union union語句的第二個或者說是後面那一個.
  • dependent union    UNION中的第二個或後面的SELECT語句,取決於外面的查詢
  • union result        UNION的結果

table:輸出的行所用的表

type:顯示連接使用了何種類型。從最好到最差的連接類型為const、eq_reg、ref、range、indexhe和all

  • const:表最多有一個匹配行,const用於比較primary key 或者unique索引。因為只匹配一行數據,所以很快記住一定是用到primary key 或者unique
  • eq_reg:mysql手冊是這樣說的:"對於每個來自於前面的表的行組合,從該表中讀取一行。這可能是最好的聯接類型,除了const類型。它用在一個索引的所有部分被聯接使用並且索引是UNIQUE或PRIMARY KEY"。eq_ref可以用於使用=比較帶索引的列。
  • ref:ref 對於每個來自於前面的表的行組合,所有有匹配索引值的行將從這張表中讀取。如果聯接只使用鍵的最左邊的首碼,或如果鍵不是UNIQUE或PRIMARY KEY(換句話說,如果聯接不能基於關鍵字選擇單個行的話),則使用ref。如果使用的鍵僅僅匹配少量行,該聯接類型是不錯的。
  • range:給定範圍內的檢索,使用一個索引來檢查行。
  • index :該聯接類型與ALL相同,除了只有索引樹被掃描。這通常比ALL快,因為索引文件通常比數據文件小。(也就是說雖然all和Index都是讀全表,但index是從索引中讀取的,而all是從硬碟中讀的)
  • ALL  對於每個來自於先前的表的行組合,進行完整的表掃描。如果表是第一個沒標記const的表,這通常不好,並且通常在它情況下差。通常可以增加更多的索引而不要使用ALL,使得行能基於前面的表中的常數值或列值被檢索出。

possible_keys:顯示可能應用在這張表中的索引。如果為空,沒有可能的索引。可以為相關的域從where語句中選擇一個合適的語句

key: 實際使用的索引。如果為null,則沒有使用索引。很少的情況下,mysql會選擇優化不足的索引。這種情況下,可以在select語句中使用use index(indexname)來強制使用一個索引或者用ignore index(indexname)來強制mysql忽略索引

key_len:使用的索引的長度。在不損失精確性的情況下,長度越短越好

ref:顯示索引的哪一列被使用了,如果可能的話,是一個常數

rows:mysql認為必須檢查的用來返回請求數據的行數,數值越大越不好,說明沒有用好索引

extra:關於mysql如何解析查詢的額外信息。using temporary和using filesort是最差的情況,意思mysql根本不能使用索引,結果是檢索會很慢

 


 extra列返回的描述的意義

distinct:一旦mysql找到了與行相聯合匹配的行,就不再搜索了

not exists: mysql優化了left join,一旦它找到了匹配left join標準的行,就不再搜索了

range checked for each record(index map:#):沒有找到理想的索引,因此對於從前面表中來的每一個行組合,mysql檢查使用哪個索引,並用它來從表中返回行。這是使用索引的最慢的連接之一

using filesort: 看到這個的時候,查詢就需要優化了。mysql需要進行額外的步驟來發現如何對返回的行排序。它根據連接類型以及存儲排序鍵值和匹配條件的全部行的行指針來排序全部行

using index: 列數據是從僅僅使用了索引中的信息而沒有讀取實際的行動的表返回的,這發生在對錶的全部的請求列都是同一個索引的部分的時候

using temporary 看到這個的時候,查詢需要優化了。這裡,mysql需要創建一個臨時表來存儲結果,這通常發生在對不同的列集進行order by上,而不是group by上

where used 使用了where從句來限制哪些行將與下一張表匹配或者是返回給用戶。如果不想返回表中的全部行,並且連接類型all或index,這就會發生,或者是查詢有問題不同連接類型的解釋(按照效率高低的順序排序)

system 表只有一行:system表。這是const連接類型的特殊情況

const:表中的一個記錄的最大值能夠匹配這個查詢(索引可以是主鍵或惟一索引)。因為只有一行,這個值實際就是常數,因為mysql先讀這個值然後把它當做常數來對待

eq_ref:在連接中,mysql在查詢時,從前面的表中,對每一個記錄的聯合都從表中讀取一個記錄,它在查詢使用了索引為主鍵或惟一鍵的全部時使用

ref:這個連接類型只有在查詢使用了不是惟一或主鍵的鍵或者是這些類型的部分(比如,利用最左邊首碼)時發生。對於之前的表的每一個行聯合,全部記錄都將從表中讀出。這個類型嚴重依賴於根據索引匹配的記錄多少—越少越好

range:這個連接類型使用索引返回一個範圍中的行,比如使用>或<查找東西時發生的情況

index: 這個連接類型對前面的表中的每一個記錄聯合進行完全掃描(比all更好,因為索引一般小於表數據)

all:這個連接類型對於前面的每一個記錄聯合進行完全掃描,這一般比較糟糕,應該儘量避免

  致謝:感謝您的閱讀! 


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

-Advertisement-
Play Games
更多相關文章
  • 還在糾結安裝oracle失敗後無法卸載的苦惱嗎?這裡教你如何徹底卸載oracle資料庫 ...
  • mysql存儲過程詳解 1. 存儲過程簡介 我們常用的操作資料庫語言SQL語句在執行的時候需要要先編譯,然後執行,而存儲過程(Stored Procedure)是一組為了完成特定功能的SQL語句集,經編譯後存儲在資料庫中,用戶通過指定存儲過程的名字並給定參數(如果該存儲過程帶有參數)來調用執行它。 ...
  • 介紹 以前一直使用centos今天需要對一臺ubantu的系統安裝mysql,雖然它也是類unix但是和redhat或centos命令上還是有點差別。 下載解壓 wget http://dev.mysql.com/get/Downloads/MySQL-5.6/mysql-5.6.33-linux- ...
  • 轉自http://www.shangxueba.com/jingyan/1940447.html 1.游標方式 複製代碼代碼如下: DECLARE @Data NVARCHAR(max) SET @Data='1,tanw,2,keenboy' --Id,Name DECLARE @dataItem ...
  • 附加資料庫時出現附加資料庫失敗的錯誤,錯誤號是5120,已經兩次遇到這種問題了。今天寫一下解決辦法。 有兩個方法,很簡單: 1.設置mdf文件所在文件夾的許可權,在文件夾上右擊——屬性——安全,如圖所示: 根據圖示進行設置即可,註意是Authenticated user的許可權。 2.不要用sa登陸你的 ...
  • 在主庫沒有數據情況下配置MYSQL的主從及讀寫分離。目前只接觸過mysql_proxy,atlas(360)的代理。現已學習一下。以備以後用到。 ...
  • 在 HBase(六): HBase體繫結構剖析(上) 介紹過,Hbase創建表時,只需指定表名和至少一個列族,基於HBase表結構的設計優化主要是基於列族級別的屬性配置,如下圖: 目錄: BLOOMFILTER BLOCKSIZE IN_MEMORY COMPRESSION/ENCODING VER ...
  • 前陣子給以同事導oracle資料庫,但是發現導入後數據都是亂碼,下麵是自己解決這個問題的一些小整理。 比如: #su oralce $export ORACLE_SID=orcl $export ORACLE_HOME=/db/oracle/product/10.2.0/db_1 $cd $ORAC ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...