如何寫出高效能SQL
定量遍歷次數
在編寫一條查詢語句的時候,可以依據你要查詢資料表的資料總量,估算一下這條查詢大致需要遍歷多少行資料:
如果遍歷行數在百萬以內的,只要不是每秒鐘都要執行幾十上百次的頻繁查詢,可以認為是安全的。
遍歷資料行數在幾百萬的,查詢時間最少也要幾秒鐘,你就要仔細考慮有沒有優化的辦法。
遍歷行數達到千萬量級和以上的,我只能告訴你,這種查詢就不應該出現在你的系統中。當然我們這裡說的都是線上交易系統,離線分析類系統另說。
遍歷行數在千萬左右,是 MySQL 查詢的一個坎兒。MySQL 中單個表資料量,也要儘量控制在一千萬條以下,最多不要超過二三千萬這個量級。原因也很好理解,對一個千萬級別的表執行查詢,加上幾個 WHERE 條件過濾一下,符合條件的資料最多可能在幾十萬或者百萬量級,這還可以接受。但如果再和其他的表做一個聯合查詢,遍歷的資料量很可能就超過千萬級別了。所以,每個表的資料量最好小於千萬級別。
避免全表索引
絕大多數情況下,我們編寫的查詢語句,都應該使用索引,避免去遍歷整張表,也就是通常說的,避免全表掃描。你在每次開發新功能,需要給資料庫增加一個新的查詢時,都要評估一下,是不是有索引可以支撐新的查詢語句,如果有必要的話,需要新建索引來支援新增的查詢。
增加索引付出的代價是,會降低資料插入、刪除和更新的效能。這個也很好理解,增加了索引,在資料變化的時候,不僅要變更資料表裡的資料,還要去變更每個索引。所以,對於更新頻繁並且對更新效能要求較高的表,可以儘量少建索引。而對於查詢較多更新較少的表,可以根據查詢的業務邏輯,適當多建一些索引。
分析 SQL 執行計劃
在 MySQL 中使用執行計劃也非常簡單,只要在你的 SQL 語句前面加上 EXPLAIN 關鍵字,然後執行這個查詢語句就可以了。
比如有一個使用者表,包含使用者 ID、姓名、部門編號和狀態這幾個欄位:
我們希望查詢某個二級部門下的所有人,查詢條件就是,部門代號以 00028 開頭的所有人。下面這兩個 SQL,他們的查詢結果是一樣的,都滿足要求,但是,哪個查詢效能更好呢?
SELECT * FROM user WHERE left(department_code, 5) = ‘00028’;SELECT * FROM user WHERE department_code LIKE ‘00028%’;
我們分別檢視一下這兩個 SQL 的執行計劃:
row 列:
MySQL 預估執行這個 SQL 可能會遍歷的資料行數。第一個 SQL 遍歷了四千多行,這就是整個 User 表的資料條數;第二個 SQL 只有 8 行,這 8 行其實就是符合條件的 8 條記錄。顯然第二個 SQL 查詢效能要遠遠好於第一個 SQL。
type 列:
表示這個查詢的訪問型別。ALL 代表全表掃描,這是最差的情況。range 代表使用了索引,在索引中進行範圍查詢,因為第二個 SQL 語句的 WHERE 中有一個 LIKE 的查詢條件。如果直接命中索引,type 這一列顯示的是 index。如果使用了索引,可以在 key 這一列中看到,實際上使用了哪個索引。
總結
在開發階段,衡量一個 SQL 查詢語句查詢效能的手段是,估計執行 SQL 時需要遍歷的資料行數。遍歷行數在百萬以內,可以認為是安全的 SQL,百萬到千萬這個量級則需要仔細評估和優化,千萬級別以上則是非常危險的。為了減少慢 SQL 的可能性,每個資料表的行數最好控制在千萬以內。 索引可以顯著減少查詢遍歷資料的數量,所以提升 SQL 查詢效能最有效的方式就是,讓查詢儘可能多的命中索引,但索引也是一把雙刃劍,它在提升查詢效能的同時,也會降低資料更新的效能。 對於複雜的查詢,最好使用 SQL 執行計劃,事先對查詢做一個分析。在 SQL 執行計劃的結果中,可以看到查詢預估的遍歷行數,命中了哪些索引。執行計劃也可以很好地幫助你優化你的查詢語句。
相關文章
- 如何寫出高效能SQL語句SQL
- 優化SQL查詢:如何寫出高效能SQL語句優化SQL
- 如何寫出高效能的Jquery程式碼jQuery
- 如何寫出效能好的sqlSQL
- 大牛們是如何寫出那些高質量、高效能的SQL查詢語句的?SQL
- 如何寫出高效能程式碼(二)巧用資料特性
- 如何寫出更快的 SQL (db2)SQLDB2
- 【譯】SQL 指引:如何寫出更好的查詢SQL
- 如何寫出高效能程式碼之優化資料訪問優化
- 如何寫出高效能程式碼之優化記憶體回收(GC)優化記憶體GC
- Ask Hoegh(7)——寫sql時如何輸出單引號?SQL
- 【譯】如何使用 Golang 中的 Go-Routines 寫出高效能的程式碼Golang
- SQL Server 高效能寫入的一些總結SQLServer
- 最佳實踐|如何寫出簡單高效的 Flink SQL?SQL
- 如何寫出高效能程式碼(一)善用演算法和資料結構演算法資料結構
- 如何編寫一個高效能的Angular元件Angular元件
- 深入理解 GIL:如何寫出高效能及執行緒安全的 Python 程式碼執行緒Python
- Go語言 如何配製 高效能sql.DBGoSQL
- 如何最有效的編寫SQLSQL
- 如何寫這個sql語句?SQL
- 如何設計出高可用、高效能的介面
- 編寫高效能JavaScriptJavaScript
- 面試官:如何在開發階段就儘量避免寫出慢 SQL ?面試SQL
- 如何寫一對多分頁的SQLSQL
- 編寫高效能的JavaScriptJavaScript
- Oracle高效能SQL調整OracleSQL
- 如何寫出漂亮的 React 元件React元件
- 如何寫好 5000 行的 SQL 程式碼SQL
- 如何寫好5000行的SQL程式碼SQL
- 編寫高效能的JavaScript事件JavaScript事件
- 如何寫出漂亮的 JavaScript 程式碼JavaScript
- 如何寫出更好的 React 程式碼?React
- 如何寫出優雅的程式碼?
- 如何寫出整潔的程式碼
- 如何寫出優美的 C 程式碼
- 如何寫出更好的Java程式碼Java
- 如何在PL/SQL中讀寫檔案(轉)SQL
- 程式設計師筆記|如何編寫高效能的Java程式碼程式設計師筆記Java