首先明確乙個問題:如果我的 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從這幾個方面教你如何選型。了解研發技術 技術是硬道理。只有過關的技術才會研發出過硬的產品。如果技術不過關,後期將會帶來一系列的問題。同時需要考慮技術的先進性。在現如今社會發展日新月異,今天還遙遙領先的管理模式也許明天就會被淘汰。所...