mysql 手把手教你給 SQL 做個優化

2021-10-08 11:46:46 字數 4275 閱讀 9590

首先明確乙個問題:如果我的 sql 語句執行的足夠快,還有沒有必要去做優化?

完全沒有必要對吧

所以我們一般說,要給 sql 做個優化,那肯定就是這條 sql 語句執行的比較慢了

那麼,為什麼它會執行比較慢呢?

這個應該是比較好理解的,如果資料比較多,在千萬級別以上,然後呢又沒有建立索引,在這千萬級別的資料中查詢你想要的內容,簡直就是在肉搏啊

索引失效這塊內容說起來就比較多了,比如在查詢的時候,讓 like 萬用字元在前面了,比如經常念叨的"最左匹配原則",又比如我們在查詢條件中使用 or ,而且 or 前後條件中有乙個列沒有索引,等等這些情況都會導致索引失效

常用的儲存引擎主要有 innodb 和 myisam 這兩種了,前者支援行鎖和表鎖,後者就只支援表鎖

如果資料庫操作都是基於表鎖的話,意思就是說,現在有個更新操作,就會把整張表鎖起來,那麼查詢的操作都不被允許,所以就不要說提高系統的併發效能了

這個也比較常見了,啥是不恰當的 sql 語句呢?就比如,明明你需要查詢的內容是 name , age ,但是呢,為了省事,直接 select * ,或者在 order by 時,後面的條件不是索引字段,這就是不恰當的 sql 語句

在知道了 sql 語句執行比較慢的原因之後,接下來要做的就是對症下藥了

針對 沒有索引/索引失效 這塊,最有效的辦法就是 explain 語法了,其實 show profile 也可以

針對 鎖等待 這塊,沒辦法了,只能自己多注意

針對 不恰當的 sql 語句 這塊,介紹幾個常用的 sql 優化,比如分頁查詢怎麼優化一下可以查詢的更快一些呀,你不是說 select * 不是正確的開啟方式嘛?那什麼是正確的 select 方式呢?***都會講講

廢話不多說,咱們開始了

為了確保優化後的結果和我寫的一樣(起碼 90% 是相符的

所以咱們用一樣的資料庫好不好

首先建個 demo 的資料庫

接下來咱們建表,就建個非常簡單的表好不好

create table demo.

table

( id int(11

) not null,

a int(11

) default null,

b int(11

) default null,

primary key

(id)

) engine = innodb

然後插入 10 萬條資料

drop procedure if exists demo_insert;

create procedure demo_insert()

begin

declare i int;

set i =1;

while i <=

100000 do

insert into demo.`table` values (i, i, i)

; set i = i +1;

end while;

end;

call demo_insert()

;

ok ,準備工作做好了,接下來開始實戰

只要說 sql 調優,那就離不開 explain

咱們能夠看到有好幾個引數:

possible_keys :表示可能使用到的索引

key :實際使用到的索引

key_len :使用的索引長度

ref :關聯 id 等資訊

rows :找到符合條件時,所掃瞄的行數,在這裡雖然有 10 萬條資料,但是因為索引的緣故,所以掃瞄了 99 行的資料

extra :額外的資訊,常見的有以下幾種

如果對這些引數了解的非常不錯,那麼 explain 這塊內容就難不住你了

通過 explain 分析執行計畫,只能說明 sql 的外部執**況,如果想要知道 mysql 具體是如何查詢的,需要通過 show profile 來分析

可以通過show profiles;語句來查詢最近傳送給伺服器的 sql 語句,預設情況下是記錄最近已經執行的 15 條記錄,如下圖我們可以看到:

我想看具體的一條語句,看到 query_id 了嘛?然後執行下show profile for query 82;這條命令就可以了:

可以看到,在結果中, sending data 耗時是最長的,這是因為此時 mysql 執行緒開始讀取資料並且把這些資料返回到客戶端,在這個過程中會有大量磁碟 i/o 操作

通過這樣的分析,我們就能知道, sql 語句在查詢過程中,到底是 磁碟 i/o 影響了查詢速度,還是 system lock 影響了查詢速度

在使用分頁查詢時,都會使用 limit 關鍵字

但是對於分頁查詢,其實還可以優化一步

我這裡給出的資料庫不是太好,因為它太簡單了,看不出來有什麼區別,我使用目前專案上正在用的表來做個實驗,可以看下區別(使用的 sql 語句如下面):

上面一張,我沒有使用子查詢,可以看到執行了 0.033s ,下面的查詢語句,我使用了子查詢去做優化,能夠看到執行了 0.007s ,優化的結果還是很顯而易見的

那麼,為什麼使用了子查詢,查詢的速度就提上來了呢,這是因為當我們沒有使用子查詢時,查詢到的 10020 行資料都返回回來了,接下來要對這 10020 行資料再進行操作

那可不可以直接就返回需要的 20 行資料呢?可以,子查詢就是在做這件事情

所以查詢時間上有了乙個很大的優化

在查詢時,有時為了省事,直接使用select * from table where id = 1這樣的 sql 語句,但是這樣的寫法在一些環境下是會存在一定的效能損耗的

所以最好的 select 查詢就是,需要什麼欄位就查詢什麼字段

一般在查詢時,都會有條件,按照條件查詢

這個時候正確的 select 開啟方式是什麼呢?

如果可以通過主鍵索引的話, where 後面的條件,優先選擇主鍵索引

為什麼呢?這就要知道 mysql 的儲存規則

mysql 常用的儲存引擎有 myisam 和 innodb , innodb 會建立主鍵索引,而主鍵索引屬於聚簇索引,也就是在儲存資料時,索引是基於 b+ 樹構成的,具體的行資料則儲存在葉子節點

也就是說,如果是通過主鍵索引查詢的,會直接搜尋 b+ 樹,從而查詢到資料

如果不是通過主鍵索引查詢的,需要先搜尋索引樹,得到在 b+ 樹上的值,再到 b+ 樹上搜尋符合條件的資料,這個過程就是"回表"

很顯然,回表能夠產生時間.

這也是為什麼建議, where 後面的條件,優先選擇主鍵索引

看完上面的,心裡應該就大概有數了, sql 調優主要就是建立索引/防止產生鎖等待/使用恰當的 sql 語句去查詢

但是,如果問你除了索引,除了上面這些手段,還有沒有其他調優方式

啥?竟然還有?!

有的,這就需要跳出來,不要侷限在具體的 sql 語句上了,需要在資料庫設計之初就考慮好

比如說,我們常說的要遵循三正規化,但是其實有些時候,表裡面有些冗餘字段帶來的效果要更好

當然了,這塊的內容可能 dba 就已經考慮好了,但是多了解一點兒也沒什麼壞處嘛

手把手教你做flash RPG

第一步 匯入資料 首先在flash中匯入人物走路的,如下圖 第二步 製作向前後左右走路的影片剪輯 把剛才匯入的,分別製作成4個影片剪輯a,d,s,w,用來描述走路的過程,如下圖 第三步 製作walk影片剪輯,在主場景中建立乙個walk影片剪輯,在walk中建立8個關鍵幀,幀標籤分別是 right l...

手把手教你做測試分析

測試分析是什麼?我們知道作為乙個測試人員,拿到需求之後,不可能上來就做測試設計,因為需求是否合理?是否有價值?是否可測試?這些問題我們沒有弄明白之前開始做測試設計是不負責任的 需求分析在需求討論會結束之後就應該被提上日常並被認真對待,那麼需求分析要分析哪些內容呢?我們用下面這個思維導圖來說明這個過程...

手把手教你OA選型

oa選型永遠是oa行業的重要焦點,在選型問題上困擾了很多客戶,雲全oa從這幾個方面教你如何選型。了解研發技術 技術是硬道理。只有過關的技術才會研發出過硬的產品。如果技術不過關,後期將會帶來一系列的問題。同時需要考慮技術的先進性。在現如今社會發展日新月異,今天還遙遙領先的管理模式也許明天就會被淘汰。所...