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

歡迎訪問 生活随笔!

生活随笔

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

数据库

mysql如何explan优化sql_《MySQL数据库》MySQL 优化SQL(explain)

發布時間:2024/4/18 数据库 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 mysql如何explan优化sql_《MySQL数据库》MySQL 优化SQL(explain) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

如果要寫出優質的SQL語句,就需要了解MySQL的存儲原理。MySQL是如何分析SQL,如何利用索引查詢。

Explain 關鍵字

explain select * from ic_base;? ? ? ? ? ? ? ? ? --查看SQL的執行情況

id:執行編號,標識Select的執行順序,存在子查詢等負責查詢的時候用來標識執行的優先順序。

select_type:?select查詢語句的類型(simple,primary,subquery,derived,union,union result,dependent union,dependent subquery)。

>?simple : 簡單SQL

>?primary?: 包含union或者子查詢,最外層的部分標記為primary

>?subquery?: 非相關子查詢(子查詢和主表之間有關聯關系)

>?derived?:?派生表——該臨時表是從子查詢派生出來的,位于form中的子查詢

>?union?: 包含union 或者 union all 的查詢

>?union result?: MySQL建立的臨時表需要去掉重復數據

>?dependent union?:?顧名思義,首先需要滿足UNION的條件,及UNION中第二個以及后面的SELECT語句,同時該語句依賴外部的查詢

>?dependent subquery?:?相關子查詢(子查詢和主表之間有關聯關系)

> materialized :當查詢優化器在執行包含子查詢的語句時,選擇將子查詢物化之后與外層查詢進行連接查詢。

table:訪問的表名

partitions:分區信息

type:?訪問類型(system > const > eq_ref > ref > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL),innodb中不存在system.一般來說,得保證查詢至少達到range級別,最好能達到ref。

>?system?:?這是const連接類型的一種特例,表只有一行數據

> const?: 主鍵索引僅有一行滿足條件

> eq_ref?:?被驅動表和驅動表通過驅動表的主鍵關聯。

> ref?: 輔助索引訪問,等值匹配或者常量匹配。

> ref_or_null?: 索引訪問,等值匹配或者常量匹配,存在null值。

> index_merge?:?合并索引,有多個索引可以選擇。

> unique_subquery?:?子查詢使用唯一索引

> index_subquery?:?子查詢使用索引

> range?:?范圍掃描,一個有限制的索引掃描。key列顯示使用了哪個索引。當使用=、<>、>、>=、、BETWEEN 和IN 操作符,用常量比較關鍵字列時。

> index?:?和全表掃描一樣。只是掃描表的時候按照索引次序進行而不是行。主要優點就是避免了排序, 但是開銷仍然非常大。

> ALL :?全表掃描

possible_keys:顯示能夠使用的索引

key:使用的索引

key_len:使用的索引長度(使用的索引字段長度之和,字段沒有設置非空,需要加1,varchar 字段還要加2)

ref:關聯列或者常數

rows:數據行數(來自統計信息)

filtered:過濾百分比,可能滿足條數/總條數

Extra:MySQL的補充額外信息

> no tables used : 沒有額外信息

> Using where : 當我們使用全表掃描來執行對某個表的查詢,并且該語句的WHERE子句中有針對該表的搜索條件

> Using index: 當我們的查詢列表以及搜索條件中只包含屬于某個索引的列,也就是在可以使用索引覆蓋的情況

> Impossible where: 查詢語句的WHERE子句永遠為FALSE時將會提示該額外信息

> Using index condition:?有些搜索條件中雖然出現了索引列,但卻不能使用到索引

> no matching min/max row:?當查詢列表處有MIN或者MAX聚集函數,但是并沒有符合WHERE子句中的搜索條件的記錄

> Using join buffer(block nested loop) : 在連接查詢執行過程中,當被驅動表不能有效的利用索引加快訪問速度,MySQL一般會為其分配一塊名叫join

buffer的內存塊來加快查詢速度

> Using filesort : 很多情況下排序操作無法使用到索引,只能在內存中(記錄較少的時候)或者磁盤中(記錄較多的時候)進行排序,這種在內存中或者磁盤上進行排序的方式統稱為文件排序(英文名:filesort)

> Using temporary : 在許多查詢的執行過程中,MySQL可能會借助臨時表來完成一些功能,比如去重、排序之類的,比如我們在執行許多包含DISTINCT、GROUP BY、UNION等子句的查詢過程中,如果不能有效利用索引來完成查詢,MySQL很有可能尋求通過建立內部的臨時表來執行查詢

> start temporary , end temporary: 查詢優化器會優先嘗試將IN子查詢轉換成semi-join,而semi-join又有好多種執行策略,當執行策略為DuplicateWeedout時,也就是通過建立臨時表來實現為外層查詢中的記錄進行去重操作時,驅動表查詢執行計劃的Extra列將顯示Start temporary提示,被驅動表查詢執行計劃的Extra列將顯示End temporary提示

> FirstMatch(表名) : 在將In子查詢轉為semi-join的去重的方式(找到一條就返回)

查詢優化器

set optimizer_trace="enabled=on";? ? ? ?--打開查詢優化器

---------------需要執行的SQL(可以使用explain)-------------------------

select * from information_schema.OPTIMIZER_TRACE? ? ?--查詢優化器的執行結果

set optimizer_trace="enabled=off";? ? ? ?--關閉查詢優化器

查詢優化器查詢的結果

query: 對應SQL.

trace :優化過程(里面有行估算,走索引,最左前綴等一些計算成本的過程,然后MySQL自動選擇一種最優方式)。

成本計算公式:全表掃描的公式: 主鍵索引頁數*1 + 行數*0.2 = Data_length/16K + Rows*0.2 ;? ? 主鍵索引頁數,行數來自統計信息, 其他數據為MySQL固定常量

由于MySQL的成本計算也是估算(99%是靠譜的),但是當遇到很復雜的SQL,或者統計信息與實際情況差距太大的時候,會導致MySQL的優化過程出現問題。

這個時候我們需要干擾MySQL的執行計劃,強制走我們需要的索引或者更新統計信息。

索引失效

1. 隱式轉換,不走索引

表ic_website的url 創建了一個普通索引,并且該字段是varchar類型,會出現一下情況:

explain select * from ic_website where url = '123';? ? --? 索引有效

explain select * from ic_website where url = 123;? ? --? 索引失效

2. <>,not in 不走普通索引,主鍵索引還是可以走索引。

explain select * from ic_website where url <> '123';

3. 左邊有% 的不走索引

explain select * from ic_website where url like '%123';

實戰

一、ANALYZE TABLE? ic_base;? ?-- 重新收集ic_base 的統計信息,保證MySQL優化器計算準確。 查看統計信息是否被更新:select * from mysql.innodb_table_stats;

select * from mysql.innodb_index_stats;

二、hints

USE INDEX:限制索引的使用范圍,們在數據表里建立了很多索引,當MySQL對索引進行選擇 時,這些索引都在考慮的范圍內。但有時我們希望MySQL只考慮幾個索引,而不是全部的索引, 這就需要用到USE INDEX對查詢語句進行設置。

IGNORE INDEX :限制不使用索引的范圍

FORCE INDEX:我們希望MySQL必須要使用某一個索引(由于 MySQL在查詢時只能使用一個索 引,因此只能強迫MySQL使用一個索引)。這就需要使用FORCE INDEX來完成這個功能。

hints 語法:

SELECT * FROM table1 USE|IGNORE|FORCE INDEX (col1_index,col2_index) WHERE col1=1 ANDcol2=2 AND col3=3;

三、straight_join? ?-- 強制改成左邊為驅動表

select t1.* fromTable1 t1 STRAIGHT_JOIN Table2 t2on t1.CommonID = t2.CommonID where t1.FilterID = 1

總結

SQL優化伴隨開發的全部過程,隨著時間和業務的推移,一些SQL的性能跟不上了,需要重新整理和優化。

筆者遇到過好幾千行的SQL(union,子查詢,嵌套查詢,函數,分組,排序)幾乎用了SQL的全部特性,優化這類SQL第一要熟悉SQL的作用,第二點要將這類SQL拆小,先找到慢的地方,然后再考慮優化。優化SQL是一個需要耐心的活,平時一定要注意SQL寫法,盡量避免一些糟糕的寫法,減少后期的維護。

總結

以上是生活随笔為你收集整理的mysql如何explan优化sql_《MySQL数据库》MySQL 优化SQL(explain)的全部內容,希望文章能夠幫你解決所遇到的問題。

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