資料庫索引設計與優化讀書筆記--《四》為SELECT語句建立理想的索引
磁碟及CPU時間的基礎假設
I/O時間:
隨機讀 | 10ms(4KB或8KB的頁) |
---|---|
順序讀 | 40MB/s |
順序掃描的CPU時間:6XZX
檢查一行記錄 | 5us |
---|---|
FETCH | 100us |
三星索引
星級是如何給定的
如果與一個查詢相關的索引行是相鄰的,或者至少相距足夠靠近的話,那這個索引就可以被標記上第一顆星。這最小化了必須掃描的索引片的寬度。
如果索引行的順序與查詢 語句的需求一致,則索引可以被標記上第二顆星。這排除了排序操作。
如果索引行包含的查詢語句中的所有列,那麼索引就可以被標記上第三顆星。這避免了訪問表的操作:僅訪問索引就可以了。
對於這三顆星,第三顆通常是最重要的。將一個列排除在索引之外可能會導致許多速度較慢的磁碟隨機讀。我們把一個至少包含第三顆星的索引成為對應查詢語句的寬索引。
寬索引:寬索引是指一個至少滿足第三顆星的索引。該索引包含了SELECT語句所涉及的所有列,因而能夠使得查詢只需訪問索引而無需訪問表。
如何構造一個三星索引
為了滿足第一顆星
首先取出所有等值謂詞的列(WHERE COL=…)。把這些列作為索引最開頭的列——以任意順序都可以。這樣,必須掃描的索引片的寬度將被縮減至最窄。
為了滿足第二顆星
將ORDER BY列加入到索引中。不要改變這些列的順序,但是忽略哪些在第一步中已經加入索引的列。由於將ORDER BY語句中的列現在加入了索引,所以結果集中的記錄無需排序就已經是以正確的順序排列了。
為了滿足第三顆星
將查詢語句中剩餘的列加入到索引中去(SELECT LNAME, CITY…),列在索引中新增的順序對查詢語句的效能沒有影響,但是將易變的列放過在最後能夠降低更新的成本,現在,索引已經包含了滿足無需回表的訪問路徑所需的所有列。
我們理想的索引有幾顆星呢?首先它必須得有第三顆星。有時候,第一顆星和第二顆星我們只能二選一。比如存在範圍謂詞時,我們(也許)不得不犧牲第二顆星來滿足一個更窄的索引片(第一顆星):
- 避免排序——擁有第二顆星
- 擁有可能的最窄索引片,不僅將需要處理的索引行數降至最低,而且將後續處理量,特別是表中資料行的同步讀,減少到最小——擁有第一顆星。
(一般情況下第一顆星比第二顆重要,但不總是這樣)。
根據星級建立最佳索引的演算法
候選A:(去掉第二顆星)
- 取出對於優化器來說不過分複雜的等值謂詞列。將這些列作為索引的前導列——以任意順序皆可。
- 將選擇性最好的範圍謂詞作為索引的下一個列,如果存在的話,最好的選擇性是指對於最差的輸入值有最低的過濾因子。只考慮對於優化器來說不過分複雜的範圍謂詞即可。
- 以正確的順序新增ORDER BY列(如果ORDER 列有DESC的話,加上DESC)。忽略在第1布或第2步中已經新增的列。
- 以任意順序將SELECT語句中的其餘的列新增至索引中(但是需要以不易變的列開始)。
候選B:(去掉第一顆星)
如果候選A引起了所給查詢語句的一次排序操作,那麼還可以設計候選B,對於候選B來說第二顆星比第一顆星更重要。
- 取出對於優化器來說不過分複雜的等值謂詞列。將這些列作為索引的前導列——以任意順序皆可。
- 以正確的順序新增ORDER BY列(如果ORDER BY列中有DESC的話,加上DESC)。忽略在第一步中已經新增的列。
由於現在的硬體條件下排序速度很快,所以如果一個程式取出結果集的所有行,那麼候選A可能和候選B一樣快,甚至比候選B更快。然而,如果一個程式只需獲取能夠填充滿一個螢幕的資料量,那麼候選B可能比候選A快很多。如果訪問路徑中沒有排序的話,資料庫管理系統只要一次一次地讀取資料行就能對結果集進行物化。如果結果集很大的話,為了產生第一屏的資料,候選A需要排序可能會花費非常長的時間。
(我的理解是:在LIMIT和OFFSET這類SQL中尤為明顯,從百萬行級的結果集中每次按順序取20行,那麼如果沒有第二顆星,每次事務都需要排序的話,那麼效率是極差的)。
設計索引的要求
機械性的為每一個查詢設計最佳索引也是不明智的,因為索引的維護可能會使得一些程式速度太慢或者使磁碟負載超負荷。實際情況中更常見的情況是,只對那些由於不合適的索引而導致速度太慢的查詢語句進行索引設計。
相關文章
- 資料庫索引設計與優化讀書筆記--《一》概述資料庫索引優化筆記
- 資料庫索引設計與優化讀書筆記--《三》SQL處理過程資料庫索引優化筆記SQL
- 高效能MySQL讀書筆記---索引優化MySql筆記索引優化
- 資料庫設計與查詢語句的優化資料庫優化
- mysql 語句的索引和優化MySql索引優化
- 為資料庫建立索引(轉)資料庫索引
- MySQL建立索引、修改索引、刪除索引的命令語句MySql索引
- 資料庫效能優化-索引與sql相關優化資料庫優化索引SQL
- MySQL 筆記 - 索引優化MySql筆記索引優化
- 資料庫引擎優化顧問與索引優化的差別資料庫優化索引
- [zt] 基於索引的SQL語句優化索引SQL優化
- Mysql索引讀書筆記(待續)MySql索引筆記
- MySQL利用索引優化ORDER BY排序語句MySql索引優化排序
- SQL提取當前庫內索引的建立語句SQL索引
- 關聯式資料庫索引設計和優化器前言資料庫索引優化
- 《Go 語言程式設計》讀書筆記(四)介面Go程式設計筆記
- 資料庫之建立索引資料庫索引
- 效能調優-Mysql索引資料結構詳解與索引優化MySql索引資料結構優化
- 資料庫索引的設計原則資料庫索引
- 資料庫建立索引的原則資料庫索引
- 如何匯出MySQL索引的建立語句MySql索引
- 資料庫 - 索引、基本表建立與刪除資料庫索引
- Mysql多列索引建立與優化.mdMySql索引優化
- 資料庫基礎知識詳解四:儲存過程、檢視、遊標、SQL語句優化以及索引資料庫儲存過程SQL優化索引
- 《MySQL慢查詢優化》之SQL語句及索引優化MySql優化索引
- mongodb資料庫如何建立索引?MongoDB資料庫索引
- ORACLE 9i資料庫優化案例(2) --- 單列索引變複合索引的優化Oracle資料庫優化索引
- MySQL優化學習筆記之索引MySql優化筆記索引
- MongoDB資料庫如何能備份集合的建索引語句?MongoDB資料庫索引
- 資料庫系統原理(四)——檢視與索引資料庫索引
- 應用索引技術優化SQL 語句(Part 3)索引優化SQL
- 應用索引技術優化SQL 語句(Part 2)索引優化SQL
- 應用索引技術優化SQL 語句(Part 1)索引優化SQL
- 資料庫效能優化之SQL語句優化資料庫優化SQL
- MySQL效能優化之索引設計MySql優化索引
- 淺談MySQL的B樹索引與索引優化MySql索引優化
- 理解索引:索引優化索引優化
- Sqlserver自動查詢缺失索引及拼出建立索引的語句的指令碼SQLServer索引指令碼