mysql 優化隱藏器 優化Sql語句,避免查詢慢

2021-10-17 19:34:25 字數 3273 閱讀 1226

前言

在面試過程中,經常會被問到,如果sql語句執行耗時過長,該如何優化sql,提高查詢效率,在此我根據自己的實際經驗,做如下總結。

一、explain分析sql語句

sql優化經常用到explain來檢視sql語句的執行計畫,以下5點是我們重點關注的地方

explain執行sql語句以後顯示的執行計畫

1、type列

通過type欄位,我們可以判斷出此次查詢是全表掃瞄還是索引掃瞄,乙個好的sql語句至少達到range級別,避免出現all級別(全表掃瞄)。

type列常用取值如下:

system:表中只有一條資料, 這個型別是特殊的const型別。

const:針對主鍵或唯一索引的等值查詢掃瞄,最多隻返回一行資料,const 查詢速度非常快, 因為它僅僅讀取一次即可。

eq_ref:表示對於前表的每乙個結果,都只能匹配到後表的一行結果,並且查詢的比較操作通常是=,查詢效率較高。

ref:此型別通常出現在多表的join查詢,針對於非唯一或非主鍵索引,或者是使用了最左字首規則索引的查詢。

range:表示使用索引範圍查詢,通過索引字段範圍獲取表中部分資料記錄,

這個型別通常出現在 =, <>, >, >=, , between, in() 操作中。

index:表示全索引掃瞄(full index scan),和all型別類似,只不過 all型別是全表掃瞄,而index型別則僅僅掃瞄所有的索引,而不是掃瞄全部資料。index型別通常出現在所要查詢的資料直接在索引樹中就可以獲取到, 而不需要掃瞄資料。當是這種情況時,extra 字段 會顯示 using index。

all:表示全表掃瞄,這個型別的查詢是效能最差的查詢之一。通常來說,我們的查詢不應該出現all型別的查詢,因為這樣的查詢在資料量大的情況下,對資料庫的效能是巨大的災難。如乙個查詢是 all 型別查詢,那麼一般來說可以對相應的字段新增索引來避免。

通常來說, 不同的 type 型別的效能關係如下:

all < index < range < ref < eq_ref < const < system

2、key列

此字段是 mysql 在當前查詢時所真正使用到的索引名。

3、key_len列

表示查詢優化器使用了索引的位元組數,這個字段可以評估組合索引是否完全被使用。

4、rows列

mysql 查詢優化器根據統計資訊,估算 sql 要查詢到結果集需要掃瞄讀取的資料行數,這個值非常直觀的顯示 sql 效率好壞, 原則上 rows 越少越好。

5、extra列

explain 中的很多額外的資訊會在 extra 字段顯示, 注意,常見的不太友好的值,如下:using filesort,using temporary。常見的有以下幾種內容:

using filesort :表示 mysql 需額外的排序操作,不能通過索引順序達到排序效果。一般有 using filesort都建議優化去掉,因為這樣的查詢 cpu 資源消耗大。

using temporary:查詢有使用臨時表,一般出現於排序,分組和多表 join 的情況,查詢效率不高,建議優化。

using index:覆蓋索引掃瞄,表示查詢在索引樹中就可查詢所需資料,不用掃瞄表資料檔案,往往說明效能不錯。

using where:表名使用了where過濾。

二、索引可能失效的情況

情況1:單獨引用復合索引裡非第一位置的索引列

復合索引遵守「最左字首」原則,即在查詢條件中使用了復合索引的第乙個字段,索引才會被使用。因此,在復合索引中索引列的順序至關重要。如果不是按照索引的最左列開始查詢,則無法使用索引。

如果有乙個2列的復合索引index(col1,col2),則已經對(col1)、(col1,col2)上建立了索引;如果有乙個3列復合索引index(col1,col2,col3),則已經對(col1)、(col1,col2)、(col1,col2,col3)上建立了索引。

情況2:對索引列運算,運算包括(+、-、*、/、!、<>、%、like』%_』(%放在前面)、or、in、exist等),導致索引失效

錯誤例子:select * from user where year(birthday) < 1990(索引失效)

正確例子:select * from users where birthday

錯誤例子:select * from user where name like '%jack%'(索引失效)

正確例子:select * from users where name like 'jack%'

情況3:索引不會包含有null值的列

只要列中包含有null值都將不會被包含在索引中,復合索引中只要有一列含有null值,那麼這一列對於此復合索引就是無效的。所以我們在資料庫表設計時不要讓字段的預設值為null,應該用0、乙個特殊的值或者乙個空串代替空值。

情況4:注意範圍查詢語句

對於聯合索引來說,如果存在範圍查詢,比如between、>、

三、如何選擇合適的列建立索引

1、在經常需要搜尋的列上,可以加快搜尋的速度;

2、在經常用在連線的列上,這些列主要是一些外來鍵,可以加快連線的速度;

3、在經常需要根據範圍進行搜尋的列上建立索引,因為索引已經排序,其指定的範圍是連續的;這樣查詢可以利用索引的排序,加快排序查詢時間;

4、在經常使用在where子句中的列上面建立索引,加快條件的判斷速度。當增加索引時,會提高檢索效能,但是會降低修改效能;

5、唯一性很差的字段不合適建索引,如性別

6、更新頻繁的字段不適合建索引,耗時且影響效能

四、索引的優缺點

優點:1、通過建立唯一性索引,可以保證資料庫表中每一行資料的唯一性。

2、可以大大加快 資料的檢索速度,這也是建立索引的最主要的原因。

3、可以加速表和表之間的連線,特別是在實現資料的參考完整性方面特別有意義。

4、在使用分組和排序子句進行資料檢索時,同樣可以顯著減少查詢中分組和排序的時間。

5、通過使用索引,可以在查詢的過程中,使用優化隱藏器,提高系統的效能。

缺點:1、建立索引和維護索引要耗費時間,這種時間隨著資料量的增加而增加。

2、索引需要佔物理空間,除了資料表佔資料空間之外,每乙個索引還要佔一定的物理空間,如果要建立聚簇索引,那麼需要的空間就會更大,如果非聚集索引很多,一旦聚集索引改變,那麼所有非聚集索引都會跟著變。

3、當對表中的資料進行增加、刪除和修改的時候,索引也要動態的維護,一旦乙個資料改變,並且改變的列比較多,可能會引起好幾個索引跟著改變,這樣就降低了資料的維護速度。

4、每個索引都有統計資訊,索引越多統計資訊越多,過多索引會導致優化器優化過程需要評估的組合增多。建立索引的時候,應該仔細考慮在哪些列上可以建立索引,在哪些列上不能建立索引。

MySQL優化 SQL優化

其實sql語句的優化核心就在避免全表掃瞄上面 對查詢語句優化,避免全表掃瞄 首先應考慮在where及order by涉及的列上建立索引 避免在where子句中對字段進行表示式和函式操作 避免where進行null 等運算導致的全表掃瞄 在group by後面增加order by null就可以防止g...

Mysql優化 SQL語句優化

索引優化 where 字段 組合索引 最左字首 索引下推 非選擇行 不加鎖 索引覆蓋 不回表 on兩邊 排序 分組 explain分析語句情況,看建立索引沒,或者建立錯誤,響應時間長的話可以看下慢查詢日誌 盡量不要用 查所有字段的話,select查詢列中的字段如果沒有索引的話,會造成回表 limit...

MySQL優化(一)常用SQL優化

一 新增 二 刪除 delete from 刪除語句加where條件,如果是刪除全部記錄,使用truncate table 表名,而不使用delete語句。三 修改 四 查詢 索引這裡就不重複了,一般在建表時對常用的查詢欄位就應該加上索引。1 單錶查詢 首先盡量只查詢單錶,可以分解成多次單錶查詢的盡...