日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

dev gridcontrol 根据数据获取索引_MySQL 索引分析除了 EXPLAIN 还有什么方法?

發布時間:2023/12/19 数据库 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 dev gridcontrol 根据数据获取索引_MySQL 索引分析除了 EXPLAIN 还有什么方法? 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

對于非數據庫開發人員而言,難以對MySQL源碼進行分析或調試,接近一個黑盒,但MySQL提供了一些命令及系統狀態變量,可對索引及其他內容進行分析。掌握這些方法后,可以盡量深入地了解MySQL的一些實現細節。

MySQL索引分析除了EXPLAIN還有什么方法

通過以下方法,可以獲得MySQL索引相關的數據,便于分析與理解索引相關的問題。

2.1. 通過慢查詢日志記錄SQL語句執行時間

參考 https://dev.mysql.com/doc/refman/5.6/en/slow-query-log.html 。

慢查詢日志中包含的SQL語句,其執行時間超過long_query_time(系統參數)秒,并且至少檢查min_examined_row_limit(系統參數)行。

獲取初始鎖的時間不包含在執行時間中。mysqld(MySQL服務器)在SQL語句執行且釋放所有鎖之后,將一條語句寫入慢查詢日志中,因此日志順序可能與執行順序不同。

2.1.1. 慢查詢日志的系統參數

long_query_time系統參數的最小值為0,默認值為10(秒)。將慢查詢日志記錄到文件時,寫入的時間包括微秒部分。將慢查詢日志記錄到表,僅寫入整數時間,微秒部分將被忽略。

默認情況下,慢查詢日志是禁用的。slow_query_log系統參數可以設置慢查詢日志是否啟用,參數值為0或OFF表示禁用,1或ON表示啟用。

slow_query_log_file系統參數用于設置日志文件名稱,默認值為“[主機名]-slow.log”。MySQL服務器會在data目錄中創建文件,除非通過絕對路徑名指定了其他目錄。

log_output系統參數用于設置通用查詢日志與慢查詢日志的輸出位置。其值為一個或多個逗號分隔的單詞組成的列表,可選值為TABLE,FILE及NONE。

  • 當指定TABLE時,表示將日志記錄到名為mysql的系統數據庫的general_log與slow_log表中;
  • 當指定FILE時,表示將日志記錄到文件中;
  • NONE表示禁用日志。

不使用索引對行進行查找的查詢,需要在啟用log_queries_not_using_indexes系統變量后,才會在寫入慢查詢日志時被包含進去。該系統默認為關閉。

查詢緩存處理的查詢不會被MySQL服務器記錄。

2.1.2. 慢查詢日志內容格式

為了通過慢查詢日志記錄查詢語句的準確耗時,需要將慢查詢日志保存至文件,log_output系統參數需要設置為FILE。慢查詢日志文件中,每條語句生成的記錄都有一行以#開頭的數據,并包含以下字段(所有字段在一行中顯示):

  • Query_time

語句執行時間,單位為秒;

  • Lock_time

獲取鎖的時間,單位為秒;

  • Rows_sent

發送給客戶端的行數;

  • Rows_examined

MySQL服務器層檢查的行數(不包含存儲引擎內部的處理)。

慢查詢日志文件中的每個語句之前都有一個SET語句,該SET語句包括一個時間戳,代表該慢查詢語句的記錄時間。

2.1.3. 開啟慢查詢日志的參數配置

為了開啟慢查詢日志,需要修改MySQL服務器使用的配置文件的“[mysqld]”節點對應的系統參數,修改配置文件并重啟MySQL服務器程序后生效。(通過“set GLOBAL 系統變量=xxx”命令修改慢查詢日志相關參數時,未生效。)系統參數設置如下所示:

slow_query_log = 1 long_query_time = 0 min_examined_row_limit = 1

設置“slow_query_log = 1”,以開啟慢查詢日志。

設置“long_query_time = 0”,將每次的查詢語句都記錄至慢查詢日志文件中。

設置“min_examined_row_limit = 1”,可以使explain語句不出現在慢查詢日志中,因為explain語句的Rows_examined為0。

slow_query_log = 1 long_query_time = 0

慢查詢日志文件默認生成在安裝目錄的data目錄中。

使用可視化數據庫管理工具連接MySQL時,可能會定時發送請求,也會生成在慢查詢日志文件中。

2.1.4. 慢查詢日志內容示例

慢查詢日志內容示例如下:

# Time: 200311 19:25:39 # User@Host: test[test] @ localhost [127.0.0.1] # Thread_id: 3 Schema: testdb QC_hit: No Query_time: 0.015360 Lock_time: 0.001452 Rows_sent: 5222 Rows_examined: 5222 use testdb; SET timestamp=1583925939; select id,cust_info from test_table_log where cust_info='1881';

經測試,以上Query_time時間僅包含MySQL服務器執行查詢操作的耗時,不包含客戶端展示數據的耗時。

2.2. 獲取SQL語句讀取索引次數

通過以下所述的方法,可以獲取SQL語句執行時,讀取的索引次數及方法,但不會顯示讀取了哪個索引。

2.2.1. SHOW STATUS語句用法

參考 https://dev.mysql.com/doc/refman/5.6/en/show-status.html 。

SHOW STATUS語句提供服務器狀態信息。該語句不需要任何特權,只要能連接到服務器即可。

SHOW STATUS語句用法如下所示:

SHOW [GLOBAL | SESSION] STATUS [LIKE 'pattern' | WHERE expr]

SHOW STATUS語句接受可選的作用域修飾符,可為GLOBAL或SESSION:

  • 當指定作用域為GLOBAL時,SHOW STATUS顯示全局的狀態值。全局狀態變量可以表示服務器本身某些方面的狀態,或者表示MySQL所有連接的匯總狀態。如果某個變量沒有全局值,則顯示會話值;
  • 當指定作用域為SESSION時,SHOW STATUS顯示當前連接的狀態變量值。如果某個變量沒有會話值,則顯示全局值。LOCAL是SESSION的代名詞;
  • 如果沒有指定作用域,默認使用SESSION。

每次調用SHOW STATUS語句都會使用一個內部臨時表,并增加全局Created_tmp_tables值。

SHOW STATUS語句支持LIKE子句,僅顯示變量名稱與指定模式匹配的行。

2.2.2. 與讀取索引次數相關的服務器狀態變量

參考 https://dev.mysql.com/doc/refman/5.6/en/server-status-variables.html 。

與讀取索引次數相關的服務器狀態變量以“HANDLER_READ”開頭,如下所示:

  • Handler_read_first

索引中第一個條目的讀取索引次數。如果該數值很高,則表明服務器正在執行很多全索引掃描(例如,SELECT col1 FROM foo,假設col1列存在索引);

  • Handler_read_key

基于索引鍵讀取行的請求數(即通過索引讀取行的數量)。如果該數值很高,則表明表的索引很合適查詢;

  • Handler_read_last

讀取索引中最后一個鍵的請求數。使用ORDER BY時,服務器將發出一個first-key請求(對應Handler_read_first),然后發出多個next-key(對應Handler_read_next)請求;使用ORDER BY DESC時,服務器將發出一個last-key(對應Handler_read_last)請求,然后發出多個previous-key(對應Handler_read_prev)請求;

  • Handler_read_next

按索引鍵順序讀取下一行的請求數。當對索引列使用范圍約束進行查詢,或進行索引掃描時,該數值會增加;

  • Handler_read_prev

按索引鍵順序讀取上一行的請求數。這種讀取方法主要用于優化ORDER BY … DESC;

  • Handler_read_rnd

基于固定位置讀取行的請求數。當執行很多需要對結果進行排序的查詢時,該數值會很高。可能有很多查詢需要MySQL掃描整個表,或者聯接未正確使用索引鍵;

  • Handler_read_rnd_next

讀取數據文件下一行的請求數(即通過全表掃描讀取行的數量)。當進行大量全表掃描時,該數值會變高。通常這表明表未正確建立索引,或者編寫的查詢未利用索引。

2.2.3. 使用SHOW STATUS獲取SQL語句讀取索引次數

當需要獲取當前會話的SQL語句讀取索引次數,可以執行SHOW STATUS查看以“HANDLER_READ”開頭的服務器狀態變量(以下執行命令中的HANDLER_READ大小寫不限):

SHOW STATUS LIKE 'HANDLER_READ%';

若需要使以上數值重置,可以重新連接MySQL服務器(創建新的會話),或重啟MySQL服務器程序。

2.2.4. SQL語句讀取索引次數示例

在以下示例中,test_table_log表的create_time字段存在單列索引,id列為主鍵。執行以下語句時,需要讀取索引中第一個記錄,Handler_read_first值加1。

select * from test_table_log order by create_time limit 1;

執行以下語句時,需要讀取索引中的最后一個記錄,Handler_read_last值加1。

select * from test_table_log order by create_time desc limit 1;

執行以下語句時,需要基于索引讀取行,Handler_read_key值加1。

select * from test_table_log where create_time = '2020/3/10 12:23:38' limit 1;

執行以下語句時,需要基于索引讀取行,Handler_read_key值加1;并需要根據索引讀取后續9行,Handler_read_next值增加9。

select * from test_table_log where create_time = '2020/3/10 12:23:38' limit 10;

執行以下語句時,共查詢到4條記錄需要基于索引讀取行,Handler_read_key值加1;并需要根據索引讀取后續行,Handler_read_next值增加4。

select * from test_table_log where id >= 'testtime1583814037num1' and id <= 'testtime1583814037num1000'

執行以下語句時,需要讀取索引中第一個記錄,Handler_read_first值加1;并需要根據索引讀取后續9行,Handler_read_next值增加9。

select * from test_table_log order by create_time limit 10;

執行以下語句時,需要讀取索引中的最后一個記錄,Handler_read_last值加1;并需要根據索引讀取之前的9行,Handler_read_prev值增加9。

select * from test_table_log order by create_time desc limit 10;

執行以下語句時,需要通過全表掃描讀取數據文件中的行,數量為110,Handler_read_rnd_next值增加110。

select * from test_table_log limit 100,10;

執行以下語句時,需要通過全表掃描讀取數據文件中的行,Handler_read_rnd_next值增加超過110;并需要對查詢到的10條記錄進行排序,Handler_read_rnd值增加10。

select a.* from ( select * from test_table_log limit 100,10 ) as a order by a.create_time;

2.2.5. 查詢數據庫表獲取SQL語句讀取索引次數(不使用)

參考 https://dev.mysql.com/doc/refman/5.6/en/status-table.html 。

INFORMATION_SCHEMA.GLOBAL_STATUS與INFORMATION_SCHEMA.SESSION_STATUS表與“SHOW GLOBAL STATUS”及“SHOW SESSION STATUS”命令顯示對應的信息。查詢示例如下:

select * from INFORMATION_SCHEMA.SESSION_STATUS where VARIABLE_NAME like 'HANDLER_READ%' and VARIABLE_VALUE <> '0' order by cast(VARIABLE_VALUE as UNSIGNED INTEGER) desc;

當從上述表查詢數據獲取SQL語句讀取索引次數時,會導致Handler_read_rnd_next變量值增大;當使用排序時,還會導致Handler_read_rnd變量值增大。因此需要獲取SQL語句讀取索引次數時,不通過上述數據庫表查詢。

2.3. 獲取InnoDB緩沖池中索引頁與記錄數

InnoDB緩沖池中索引頁與記錄數,可以反映MySQL在執行SQL語句時,將指定表的索引讀取到緩沖池中的索引頁及記錄數量。

若需要重置InnoDB緩沖池相關數據,需要重啟MySQL服務器程序(未找到其他方法清空InnoDB緩沖池)。

2.3.1. INNODB_BUFFER_PAGE表

參考 https://dev.mysql.com/doc/refman/5.6/en/innodb-information-schema-buffer-pool-tables.html 。

InnoDB INFORMATION_SCHEMA緩沖池表提供了緩沖池狀態信息,以及有關InnoDB緩沖池頁面的元數據。

InnoDB INFORMATION_SCHEMA緩沖池表中包含INNODB_BUFFER_PAGE,該表保存InnoDB緩沖池中每個頁的信息。查詢INNODB_BUFFER_PAGE或INNODB_BUFFER_PAGE_LRU表可能會影響性能,應避免在生產環境查詢。

2.3.2. INNODB_BUFFER_PAGE表字段

參考 https://dev.mysql.com/doc/refman/5.6/en/innodb-buffer-page-table.html 。INNODB_BUFFER_PAGE表中包含以下關注的字段:

  • POOL_ID

緩沖池ID。是用于區分多個緩沖池實例的標識符。

  • SPACE

表空間ID。

  • PAGE_NUMBER

頁編號(page number)。

  • PAGE_TYPE

頁的類型。例如“INDEX”代表B+樹節點,“BLOB”代表未壓縮的BLOB頁等。

  • TABLE_NAME

頁所屬的表名。該列僅適用于PAGE_TYPE值為INDEX的頁。

  • INDEX_NAME

頁所屬的索引名。可以是聚簇索引或二級索引的名稱。該列僅適用于PAGE_TYPE值為INDEX的頁。

  • NUMBER_RECORDS

頁的記錄的數量。

2.3.3. 從INNODB_BUFFER_PAGE表獲取InnoDB緩沖池中索引頁與記錄數

從INNODB_BUFFER_PAGE表中可獲取InnoDB緩沖池中索引頁與記錄數,table_name字段的形式為“`[數據庫名]`.`[表名]`”。

查詢的示例語句如下,page_num為指定表的指定索引在InnoDB緩沖池中的頁的總數,record_num為指定表的指定索引在InnoDB緩沖池中記錄的總數:

select TABLE_NAME,INDEX_NAME,count(*) as page_num,sum(NUMBER_RECORDS) as record_num from INFORMATION_SCHEMA.INNODB_BUFFER_PAGE where table_name = '`testdb`.`test_table_log`' group by TABLE_NAME,INDEX_NAME order by page_num desc;

查詢結果如下所示:

2.4. 獲取InnoDB索引頁操作次數

InnoDB對索引頁的操作包括讀取、創建及寫入等。

若需要重置上述數據,需要重啟MySQL服務器程序。

2.4.1. 使用SHOW STATUS獲取InnoDB索引頁操作次數

參考 https://dev.mysql.com/doc/refman/5.6/en/server-status-variables.html 。

MySQL服務器狀態中,包含以下與InnoDB索引頁操作次數相關的狀態:

  • Innodb_buffer_pool_pages_data

InnoDB緩沖池中包含數據的頁數。該數量包含臟頁與非臟頁。

  • Innodb_pages_created

對InnoDB表操作創建的頁數。

  • Innodb_pages_read

對InnoDB表操作,從InnoDB緩沖池讀取的頁數。

  • Innodb_pages_written

對InnoDB表操作導致被寫的頁數。

使用SHOW STATUS獲取InnoDB索引頁操作次數時,可執行以下語句:

SHOW STATUS LIKE 'Innodb_pages_%'; SHOW STATUS LIKE 'Innodb_buffer_pool_pages_data';

2.4.2. 查詢數據庫表獲取InnoDB索引頁操作次數

參考 https://dev.mysql.com/doc/refman/5.6/en/innodb-buffer-pool-stats-table.html 。

INFORMATION_SCHEMA.INNODB_BUFFER_POOL_STATS表提供了許多與“SHOW ENGINE INNODB STATUS”輸出相同的緩沖池信息。

上述表包含以下關注的列:

  • DATABASE_PAGES

InnoDB緩沖池中包含數據的頁數。該數量包含臟頁與非臟頁。

與“SHOW STATUS”輸出中的Innodb_buffer_pool_pages_data相同。

  • NUMBER_PAGES_READ

讀取的頁數。

與“SHOW STATUS”輸出中的Innodb_pages_read相同。

  • NUMBER_PAGES_CREATED

創建的頁數。

與“SHOW STATUS”輸出中的Innodb_pages_created相同。

  • NUMBER_PAGES_WRITTEN

寫入的頁數。

與“SHOW STATUS”輸出中的Innodb_pages_written相同。

從上述表獲取InnoDB索引頁操作次數示例語句如下(查詢操作不會導致以上參數變化):

select DATABASE_PAGES, NUMBER_PAGES_READ, NUMBER_PAGES_CREATED, NUMBER_PAGES_WRITTEN from INFORMATION_SCHEMA.INNODB_BUFFER_POOL_STATS;

2.4.3. 使用SHOW ENGINE STATUS獲取InnoDB索引頁操作次數(不使用)

參考 https://dev.mysql.com/doc/refman/5.6/en/show-engine.html 。

“SHOW ENGINE”顯示指定存儲引擎的操作信息。執行時需要“PROCESS”權限。

“SHOW ENGINE INNODB STATUS”顯示來自標準InnoDB監控器的有關InnoDB存儲引擎狀態的大量信息。

以上輸出信息全部包含在Status字段中,無法進行過濾,不方便單獨查看Pages read, created, written等參數。

2.5. 獲取索引頁分裂次數

參考 https://dev.mysql.com/doc/refman/5.6/en/index-page-merge-threshold.html ,頻繁發生頁分裂可能對性能產生影響。

2.5.1. INFORMATION_SCHEMA.INNODB_METRICS表

參考 https://dev.mysql.com/doc/refman/5.6/en/innodb-metrics-table.html 。

INFORMATION_SCHEMA.INNODB_METRICS表提供了InnoDB的各種性能信息。

每個監控器代表InnoDB源代碼中用于收集計數器(counter)信息的位置。每個計數器可被啟動、停止及重置。

默認情況下,收集的數據比較少。為了啟動、停止及重置計算器,需要對系統變量innodb_monitor_enable、innodb_monitor_disable、innodb_monitor_reset或innodb_monitor_reset_all進行設置。

INFORMATION_SCHEMA.INNODB_METRICS表包含以下關注的列:

  • NAME

計數器的唯一名稱;

  • COUNT

計數器啟用后的計數值;

  • STATUS

enabled代表計數器在執行,disabled代表已停止;

  • COMMENT

計數器描述。

在查詢INFORMATION_SCHEMA.INNODB_METRICS表時,需要有PROCESS權限。

在INFORMATION_SCHEMA.INNODB_METRICS表中,存在NAME為“index_page_splits”,COMMENT為“Number of index page splits”的記錄,即索引頁分裂次數對應的計數器,COUNT列為索引頁分裂次數。

select count from INFORMATION_SCHEMA.INNODB_METRICS where name='index_page_splits';

2.5.2. 啟用索引頁分裂次數計數器

參考 https://dev.mysql.com/doc/refman/5.6/en/innodb-information-schema-metrics-table.html 。

全局變量innodb_monitor_enable、innodb_monitor_disable可分別用于啟用、禁用記數器。命令如下所示:

SET GLOBAL innodb_monitor_enable = index_page_splits;SET GLOBAL innodb_monitor_disable = index_page_splits;

innodb_monitor_enable變量還可以MySQL配置文件的[mysqld]節點進行配置,可使用半角逗號對多項進行分隔。innodb_monitor_disable不支持在MySQL配置文件配置。

經驗證,對以上系統變量進行設置時,需要有SUPER權限(root用戶)。

2.6. 獲取執行計劃

參考 https://dev.mysql.com/doc/refman/5.6/en/explain-output.html 。

EXPLAIN語句提供有關MySQL如何執行語句的信息。EXPLAIN適用于SELECT,DELETE,INSERT,REPLACE和UPDATE語句。

EXPLAIN為SELECT語句中使用的每個表返回一行信息。輸出中的表的順序,與MySQL在處理語句時讀取表的順序一致。

2.6.1. EXPLAIN輸出列

EXPLAIN輸出的列及含義如下所示:

2.6.2. id

id列為SELECT的標識符,其值為查詢中SELECT的順序號。

即id列反映了SELECT在執行時的順序(從小到大)。

2.6.3. select_type

select_type列為SELECT的類型,select_type值及含義如下所示:

DEPENDENT通常表示使用了相關子查詢(correlated subquery)。

2.6.4. type

type列為連接類型,描述了表的連接方式。不同的連接類型如下所示:

  • system

表只有一行(系統表)。system是const連接類型的特例。

  • const

查詢的開頭讀取的表,最多只有一行匹配。因為只有一行,優化器的其余部分可以將此行中對應列的值視為常量。

const連接類型對應的表查詢非常快,因為它們只讀取一次。

將主鍵或唯一索引的所有部分與常量值進行比較時會使用const連接類型。

在以下示例中,tbl_name表可以作為const連接類型使用:

SELECT * FROM tbl_name WHERE primary_key=1;SELECT * FROM tbl_name WHERE primary_key_part1=1 AND primary_key_part2=2;
  • eq_ref

對于先前的表的每種行組合,從eq_ref連接類型對應的表中讀取一行。除了system和const連接類型外,eq_ref是最好的聯接類型。當連接使用索引的所有部分并且索引是主鍵或非空唯一索引時,將使用eq_ref連接類型。

eq_ref可用于使用=運算符進行比較的索引列。比較值可以是常量,也可以是使用在此表之前讀取的表中列的表達式。

在以下示例中,MySQL可以使用eq_ref連接類型處理ref_table表:

SELECT * FROM ref_table,other_table WHERE ref_table.key_column=other_table.column;SELECT * FROM ref_table,other_table WHERE ref_table.key_column_part1=other_table.column AND ref_table.key_column_part2=1;
  • ref

對于先前的表的每種行組合,從ref連接類型對應的表讀取所有具有匹配索引值的行。

如果連接僅使用索引鍵的最左前綴或者索引鍵不是主鍵或唯一索引(即連接不能基于索引鍵值選擇單行),則使用ref連接類型。

如果使用的鍵只匹配少量幾行,則ref是一個好的連接類型。

ref連接類型可用于使用=或<=>運算符進行比較的索引列。

在以下示例中,MySQL可以使用ref連接類型處理ref_table表:

SELECT * FROM ref_table WHERE key_column=expr;SELECT * FROM ref_table,other_table WHERE ref_table.key_column=other_table.column;SELECT * FROM ref_table,other_table WHERE ref_table.key_column_part1=other_table.column AND ref_table.key_column_part2=1;
  • fulltext

使用全文索引執行連接。

  • ref_or_null

ref_or_null與ref類似,區別在于使用ref_or_null時,MySQL對包含NULL值的行進行了額外搜索。

ref_or_null連接類型最常用于解決子查詢。

在以下示例中,MySQL可以使用ref_or_null連接類型處理ref_table表:

SELECT * FROM ref_table WHERE key_column=expr OR key_column IS NULL;
  • index_merge

index_merge連接類型表示使用了索引合并優化。在這種情況下,輸出行中的key列包含使用的索引列表,key_len列包含所用索引的最長鍵部分列表。

  • unique_subquery

unique_subquery連接類型在某些使用IN的子查詢的情況下替代eq_ref,如下所示:

value IN (SELECT primary_key FROM single_table WHERE some_expr)

unique_subquery只是一個索引查找函數,可以完全替代子查詢以提高效率。

  • index_subquery

index_subquery連接類型與unique_subquery類似,它替代了IN子查詢,支持子查詢中的非唯一索引,如下所示:

value IN (SELECT key_column FROM single_table WHERE some_expr)
  • range

range連接類型表示僅檢索給定范圍內的行,使用索引選擇行。

EXPLAIN輸出行中的key列表示使用哪個索引。key_len列包含使用的最長的索引鍵部分。對于此連接類型,ref列為NULL。

使用=,<>,>,> =,<,<=,IS NULL,<=>,BETWEEN,LIKE或IN()運算符中的任何一個將索引鍵列與常量進行比較時,可以使用range類型。

  • index

index連接類型與ALL類型類似,區別在于index連接類型有對索引樹進行掃描。有兩種方式:a. 如果查詢的索引是覆蓋索引,并且可滿足所需表的所有數據,則僅掃描索引樹。在這種情況下,Extra列顯示“Using index”。僅掃描索引通常比ALL連接類型快,因為索引的大小通常小于表數據。b. 對指定索引讀取數據,進行全表掃描,以按索引順序查找數據行。Extra列不會顯示“Using index”。

當查詢僅使用屬于單個索引一部分的列時,MySQL可以使用此連接類型。

  • ALL

對之前的表中的每個行組合進行全表掃描。

如果當前表是第一個沒有標記為const的表,這通常是不好的,并且通常在所有其他情況下非常糟糕。

通常,可以通過添加索引來避免ALL連接類型,這些索引基于常量值或先前的表的列值,啟用從該表的行檢索。

2.6.5. possible_keys

possible_keys列表示MySQL可以選擇用于查找此表的行的索引。請注意,此列于EXPLAIN輸出中顯示的表的順序完全獨立。

假如possible_keys列為NULL,說明沒有相關的索引。

2.6.6. key

key列表示MySQL實際決定使用的索引鍵。如果MySQL決定使用其中一個possible_keys索引來查找行,那么該索引將被顯示在key列中。

如果key列為NULL,說明MySQL未找到更有效執行查詢的索引。

要強制MySQL使用或忽略possible_keys列中列出的索引,請在查詢中使用FORCE INDEX,USE INDEX或IGNORE INDEX。

2.6.7. key_len

key_len列表示MySQL決定使用的索引鍵的長度。根據key_len的值可以確定MySQL實際使用了聯合索引的多少部分。

由于索引鍵的存儲格式,可以為NULL的列比不允許為NULL的列的索引鍵長度大1。

2.6.8. ref

ref列顯示了在key列中列出的,用于從表中查詢行的索引,與哪些列或常量進行了比較。

如果ref列的值為func,說明使用的值是某些函數的結果。

2.6.9. rows

rows列表示MySQL認為執行查詢時必須檢查的行數。

對于InnoDB表,該數字是估計值,可能并不總是準確的。

2.6.10. Extra

Extra列包含MySQL如何解決查詢的額外信息。以下為Extra列的部分可能的值及說明:

  • Using filesort

出現該提示說明MySQL在進行排序時需要使用filesort,未使用索引進行排序。

  • Using index

從表中檢索列信息時,僅使用索引樹的信息,不需要進行額外的查找以讀取實際行。

當僅查詢屬于單個索引的部分列時,可以使用此策略。

對于具有用戶定義的聚簇索引的InnoDB表,即使Extra列中沒有出現“Using index”,對應的索引也可能被使用。當type列為index且key列為主鍵時,對應以上情況。

  • Using index condition

出現該提示說明MySQL在查詢時使用了索引條件下推。

  • Using sort_union(…), Using union(…), Using intersect(…)

以上顯示了對應index_merge連接類型,即使用索引合并時,索引掃描合并時使用的特定算法。

  • Using temporary

為了解決該查詢,MySQL需要創建一個臨時表來保存結果。如果查詢包含GROUP BY和ORDER BY子句,且列出了不同的列時,通常會發生這種情況。

  • Using where

WHERE子句用于限制與下一個表匹配的行,或發送到客戶端的行。假如Extra列的值不是using where,且表的連接類型為ALL或index時,則說明查詢語句存在一些問題,除非是特意為了獲取或檢查表中所有的行。

3. InnoDB讀取索引頁時機

InnoDB讀取索引頁的時機,包括但不限于MySQL啟動、執行EXPLAIN語句、執行查詢/插入/更新操作等情況。

為了獲取InnoDB讀取索引頁的次數,可參考前文,查詢以“Innodb_pages_”開頭的系統狀態,或從INFORMATION_SCHEMA.INNODB_BUFFER_POOL_STATS表查詢。

3.1. MySQL啟動時讀取索引頁

當MySQL啟動時,會讀取對部分表的索引。此時還未執行任何語句,查看InnoDB讀取索引頁的次數大于0,查看InnoDB緩沖池中索引頁與記錄數大于0。

3.2. 執行EXPLAIN語句時讀取索引頁

在執行EXPLAIN語句時,可能會讀取相關表對應的索引頁,若所需的索引頁數據已被讀取至緩沖池中,可能不會讀取。對于上述情況,可查看InnoDB讀取索引頁的次數,執行EXPLAIN語句后次數會增加。

3.3. 執行插入/查詢/更新/刪除語句時讀取索引頁

在執行插入/查詢/更新/刪除語句時,可能會讀取相關表對應的索引頁,若所需的索引頁數據已被讀取至緩沖池中,可能不會讀取。

4. 參考資料

以上參考的資料如下:https://dev.mysql.com/doc/refman/5.6/en/


原作者:adrninistrat0r
原文鏈接:MySQL 索引分析除了 EXPLAIN 還有什么方法?
原出處:csdn公眾號
侵刪

總結

以上是生活随笔為你收集整理的dev gridcontrol 根据数据获取索引_MySQL 索引分析除了 EXPLAIN 还有什么方法?的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。