1. 程式人生 > >MYSQL explain詳解之range

MYSQL explain詳解之range

explain顯示了MySQL如何使用索引來處理DML語句以及連線表,explain顯示的資訊可以幫助選擇更好的索引和寫出更優化的查詢語句

 2.EXPLAIN列的解釋:

table:顯示這一行的資料是關於哪張表的

type:這是重要的列,顯示連線使用了何種型別。從最好到最差的連線型別為const、eq_reg、ref、range、 indexhe和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根本不能使用索引,結果是檢索會很慢

3.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:這個連線型別對於前面的每一個記錄聯合進行完全掃描,這一般比較糟糕,應該儘量避免.

優化器中range的使用案例:

在尋求優化的時候需瞭解3點:

1、表的DDL

2、SQL語句

3、EXPLIAN 

CREATE TABLE `account` (

  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '使用者資金賬戶',

  `user_id` bigint(20) DEFAULT NULL COMMENT '使用者ID',

  `amount` decimal(10,2) DEFAULT '0.00' COMMENT '總金額',

  `available` decimal(10,2) DEFAULT '0.00' COMMENT '可用餘額',

  `presented` decimal(10,2) DEFAULT '0.00' COMMENT '活動贈送金額',

  `deposit_amount` decimal(10,2) DEFAULT '0.00' COMMENT '押金金額',

  `freeze_amount` decimal(10,2) DEFAULT NULL COMMENT '凍結金額',

  `status` tinyint(4) DEFAULT NULL COMMENT '賬戶狀態',

  `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '建立時間',

  `update_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新時間',

  PRIMARY KEY (`id`),

  UNIQUE KEY `uid_index` (`user_id`) USING BTREE,

  KEY `create_time` (`create_time`)

) ENGINE=InnoDB AUTO_INCREMENT=6184535 DEFAULT CHARSET=utf8

#######

EXPLAIN SELECT * FROM account WHERE id>1

id select_type  table typepossible_keyskey  key_lenref   rowsExtra

1SIMPLE    account rangePRIMARY     PRIMARY 8      2808936Using where

看起來好像走了RANGE......

EXPLAIN SELECT * FROM account WHERE user_id>1 

id select_typetabletypepossible_keyskeykey_lenref rows   Extra

1SIMPLE   accountALL    uid_index        5617872  Using where

這裡出問題了吧.....

EXPLAIN SELECT * FROM account WHERE user_id>1   AND user_id<2222

id select_typetable typepossible_keyskey    key_lenref rows    Extra

1SIMPLE   account range uid_index uid_index  9     2218Using index condition

#第一個看起來是走了range,實際是因為primary key 起決定性因素

在第2個有索引但全表掃描,只有開區間沒有

在第3個包含了開區間和閉區間直接走了range

由此:在SQL優化時候,如果要使用range來實現索引,必須滿足有開始點和結束點,俗稱開區間和閉區間。

比如在時間欄位上新增2級索引,如:

SELECT * FROM account WHERE create_time>DATE_FORMAT("2017-01-26",'%Y-%m-%d') AND create_time<DATE_FORMAT("2017-01-29",'%Y-%m-%d')

SELECT * FROM account WHERE create_time>DATE("2017-01-26")AND create_time <DATE("2017-01-29")

SELECT * FROM account WHERE create_time>STR_TO_DATE("2017-01-26",'%Y-%m-%d')AND create_time <STR_TO_DATE("2017-01-29",'%Y-%m-%d')

id  select_typetabletypepossible_keyskey     key_lenrefrowsExtra

1    SIMPLE   accountrangecreate_time  create_time6    129610Using index condition

一般WHERE條件裡包含函式是不能走索引的,前提是不靠近WHERE時候就能生效

相關推薦

MYSQL explainrange

explain顯示了MySQL如何使用索引來處理DML語句以及連線表,explain顯示的資訊可以幫助選擇更好的索引和寫出更優化的查詢語句  2.EXPLAIN列的解釋: table:顯示這一行的資料是關於哪張表的 type:這是重要的列,顯示連線使用了何種型

MySQL explain

null pen head 並不是 階段 後者 訪問類 union 查找 explain命令的使用及相關參數說明。 https://dev.mysql.com/doc/refman/5.7/en/explain-output.html EXPLAIN Output Colu

MySQL Explain

索引查找 ID dex 分別是 重新 system 類型 bsp 常常 在日常工作中,我們會有時會開慢查詢去記錄一些執行時間比較久的SQL語句,找出這些SQL語句並不意味著完事了,些時我們常常用到explain這個命令來查看一個這些SQL語句的執行計劃,查看該SQL語句有沒

mysqlexplain(分析索引的最佳使用)

在這裡對explain的各個欄位進行詳細的分析,來幫助大家分析自己所寫的sql是否最佳的使用了索引。 首先是select_type:將select查詢分為簡單(simple)和複雜兩種型別 複雜型別又分為子查詢(subquery)和from列表中包含子查詢(drive

Mysql EXPLAIN

在mysql得使用中,查詢效率低下,除cpu,io或硬體得限制外,作為java程式設計師我們主要關注得還是sql得優化。    使用 EXPLAIN 檢視sql執行計劃    它可以做什麼 1.表得讀取順序   2.資料讀取操作得操作型別   3.哪些索引可以使用   4.哪

mysql數據庫 自學成才1

簡化 註意 可能 方法 after 字符型 專題 mar 建議 一、學習目錄 1.認識數據庫和mysql 2.mysql連接 3.入門語句 4.詳解列類型 5.增刪改查 INSERT INTO 表名(列1,…… 列n) VALUES(值 1,…… 值 n); *(列

mysql - 慢查詢日誌、explain

一 開啟慢查詢日誌 show variables like 'slow_query_log'; show variables like 'slow_query%'; show variables like 'long_query_time'; set global slow

JDBCmySQL資料庫的連線和基本操作一

JDBC詳解 JDBC詳解 一 JDBC基本操作 MySQL的JDBC驅動包: mysql-connector-java-5.1.3

史上最簡單MySQL教程(基礎篇)多表聯合查詢

常用術語 內連線 外連線 左外連線 右外連線 注意事項: 自連線 子查詢 在上篇文章史上最簡單MySQL教程詳解(基礎篇)之資料庫設計正規化及應用舉例我們介紹過,在關係型資料庫中,我們通常為了減少資料的冗餘量將對資料表進行規範,將

關聯查詢和多次查詢的點 以及 MySQL慢查詢優化 EXPLAIN

        對於欄位比較多的表,如果有些欄位的使用頻率很低,可以將這些欄位分離出來形成新表。因為當一個表的資料量很大時,會由於使用頻率低的欄位的存在而變慢。2. 增加中間表        對於需要經常聯合查詢的表,可以建立中間表以提高查詢效率。通過建立中間表,把需要經常聯合查詢的資料插入到中間表中,然後將

史上最簡單MySQL教程(進階篇)儲存引擎介紹及預設引擎設定

什麼是儲存引擎? 與其他資料庫例如Oracle 和SQL Server等資料庫中只有一種儲存引擎不同的是,MySQL有一個被稱為“Pluggable Storage Engine Architecture”(可替換儲存引擎架構)的特性,也就意味著My

mysql效能分析--explain和profiling開銷(資源分配)

explain id:select識別符號。select查詢序列號,即sql語句執行的順序。當有子查詢時,id就會出現不一致,如子查詢sql的id是1,外查詢sql的id是2. selecttype:select型別。simple,標示簡單的select,沒有union和子

mysql效能優化------explain

1.explain作用 explain語句提供了MySQL如何執行語句的資訊。解釋選擇、刪除、插入、替換和更新語句如何工作。 2.如何使用 explain your command; se

跟我學pythonmysql操作 一、查詢操作

  在python中,我們使用PyMySQL來操作mysql。   一、安裝PyMySQL:    使用pip進行安裝,命令為:    pip install PyMySQL   二、在進行操作之前,首先要開啟本機的mysql,或者,可以直接連線遠端已經開啟的mysql。

Mysql 效能優化Explain

explain 功能我們在日常使用中,使用慢查詢找到執行時間比較久的查詢,然後使用SHOW STATUS、SHOW PROFILE、和explain做單條語句的分析。使用explain關鍵字可以模擬優化器執行sql查詢語句,從而知道Mysql是如何處理你的sql語句的。分析你的查詢語句或者表結構的效能瓶頸。

解決ajax跨域的方法原理Cors方法

詳細 不同 htm 渲染 jsonp del 需要 methods href 1、神馬是跨域(Cross Domain) 對於端口和協議的不同,只能通過後臺來解決。 一句話:同一個ip、同一個網絡協議、同一個端口,三者都滿足就是同一個域,否則就是 跨域問題了。而為

javascript設計模式命令模式

這一 clas 例子 別了 logs 操作 book 技術 概念   每種設計模式的出現都是為了彌補語言在某方面的不足,解決特定環境下的問題。思想是相通的。只不過不同的設計語言有其特定的實現。對javascript這種動態語言來說,弱類型的特性,與生俱來的多態性,導致某些設

MVCAjax.BeginForm使用更新列表

分布 use html text col 返回 uno pts scripts 1.首先,請在配置文件設置如下:(該項默認都存在且為true) <add key="UnobtrusiveJavaScriptEnabled" value="true" /> 2

mysql 索引

mysqlmysql 索引詳解

hibernate 表關系映射繼承關系

子類 用戶 .cn cnblogs -1 擁有 nat src 實體類 舉例:亞馬遜的網上商城可以賣很多東西,比如說圖書,電器,水果等等,那麽我們以面向對象的理念去抽象一個商品類,他具有商品的共有屬性,比如說上架時間,當前 價格,優惠價格等待,商品可以繼承商