前言:系統對磁碟i/o操作是相對於cpu的處理來說如同蝸牛,但日常開發中,從磁碟讀取檔案或者持久化資料到本地卻是必不可少的操作,執行sql語句,最終的結果操縱i/o,如果sql寫了效率低下的sql語句或者設計很爛的表結構,程式執行速度就會大打折扣,所以要sql語句除了完成基本功能之外,優化是必不可少的。比較簡單的就是也是最基本的優化方式就是給資料庫表新增適合索引,提公升查詢效能。
1.索引是如何加快資料查詢速度的
合理使用索引能大大提公升查詢效能,就要理解mysql是如何組織和維護索引的。
1)索引是儲存引擎用於快速找到記錄的一種資料結構,這是索引的基本功能之一。注[1]
2)人們談論的經藏談論的索引,如果沒有特別指明,那多半是指b-tree索引。注[2]
1.1.當你給資料庫新增索引的時候,可以選擇索引方法,一般是b-tree,如圖1.1,新增索引之後,mysql負責索引組織和維護。
圖 1.1 新增索引
1.2 .b-tree索引樹(多路平衡查詢樹)的一般組織形式如下圖,圖1.2和更多樹形結構以及b-tree更詳細的介紹參見
1.2 b-tree樹
因為b-tree索引樹的組織特殊組織方式,如果這個索引是主鍵索引,那麼在當前節點的葉子頁(葉子頁是乙個沒有指向其子節點的特殊節點,但是葉子也中存放的是被索引的資料行)中存放對應的資料行,根據索引找到主鍵,就能找到得到對應的資料,試想如果沒有索引,mysql勢必會採取全表掃瞄的方式去查詢資料記錄,就要從磁碟大量讀取,比較,再讀取......速度自然不會快了。
2.如何檢視sql的執行過程,是否走了索引
如果你想要通過新增索引的方式優化你的sql語句,首先你要知道sql語句時怎麼執行,通過mysql中的
explain
關鍵字,可以檢視sql執行計畫,執行sql之後看到如下資訊(在圖形化介面工具中的暫時效果)。
圖 2.1 檢視sql執行計畫
表中的資訊重點關照 type 字段,key欄位,rows欄位(關於表中各個欄位的詳細介紹參見這篇文章:
)2.1 上來先看rows:為了找到目標數,mysql預估需要掃瞄的記錄條數,數字越小效率越高,那你就得去找原因了,接著往下看
2.2 type:指的是資料訪問型別,大白話說就是採取什麼方式去找到你需要的資料,其中比較常見的type型別的值如下(注意不同查詢方式):
1)all:掃瞄表,最低效的方式,如果資料訪問型別為all,那就說明查詢沒有走索引, 或者索引失效了,在你查詢資料不走索引的時候你應該考慮要建索引了
2.2.1 無索引查詢,即便只查詢一條資料 ,也會掃瞄很多記錄
2)index:掃瞄索引區,不掃瞄資料區
3)rang:範圍掃面。表明查詢肯定走索引了,再一定範圍進行了掃面:比如新增了索引,但是查詢的時候是用模糊查詢,且字段前面是確定的,或者查詢沒有走索引,但是在篩選(where條件語句)資料的時候給出了明確限定了範圍。如果查詢的字段沒有新增索引,那麼此處的模糊查詢仍然 是掃瞄全表。在優化sql語句的時候最差要優化到這一層次。
4)ref:通過普通索引進行查詢,可能命中乙個記錄,也有可能命中多個記錄,效能比讓rang猛。如下圖:
2.3 possible_key : 當前表可能用到的索引,可以有乙個,也可以有多個
2.4 key : 本次查詢實際用到的索引,如果時全表掃瞄,則不會用到索引,本欄則為null,查詢壓根沒有索引,要考慮優化
3 sql優化的一般思路:
1)新增適當的索引,索引字段必須要能最大限度的區分全表資料,才能達到比較好的效果。
2)在查詢語句中帶上where條件,過濾條件最好已經新增了索引,可以避免全表掃瞄。
3)注意索引失效問題。
前置模糊查詢會導致索引失效;
索引字段參與函式計算會導致索引失效
在篩選條件中or關鍵字的兩端,乙個欄位有索引,另一字段無索引, 索引失效
隱式轉換,穿入字段型別和索引字段型別不一樣,但是能匹配上,mysql 就會在不改變字段內容的前提下,把出入字段轉換成資料庫中對應的字段型別進行匹配,此時也不走索引。
4)在使用復合索引的時候要要遵循最左原則,篩選條件中的字段順序和復合索 引的字段順序保持一致
5)需要哪些欄位就查詢哪些字段,不要用*號,避免過多回表操作
6)sql優化的其他思路:
i.對熱點資料進行快取,
ii.讀寫分離主從架構
iii.分庫分表,應用曾開發難度大,一般不這麼玩,常用的分庫分表中介軟體有mycat,sharing-jdbc。
4 sql優化時很有必要了解的其它東西:注[3]
1)聚簇索引:不是一種單獨的索引型別,而是一種資料儲存結構,「聚簇」的字面意思是:資料行和和相鄰的鍵值緊湊的儲存在一起,在同乙個結構同時儲存了索引值
和資料行,在索引的葉子頁中儲存了索引對應的完整的資料記錄,找到索引,就能找到對應的資料。一張資料庫表有且只有乙個聚簇索引,因為不能把
同乙個資料同時儲存在不同地方。注意,資料行是儲存在葉子頁中,但是節點頁只有索引行。
2) 覆蓋索引:如果索引的葉子節點中已經包含了要查詢的資料,那就不必回表,乙個索引包含了所需查詢的字段的值,就稱之為覆蓋索引,覆蓋索引必須儲存索引列
的值。3)回表:出現回表操作的根本原因:二級索引(輔助索引)指的是除了主鍵索引之外的索引,因為二級索引樹葉子節點中儲存的不是索引值對應的資料行,二級索引中
儲存的『行指標』不是指向行的物理位置,而是指向行的主鍵值,要再次根據主鍵值再次到表中查詢資料行,於是就產生了回表操作。
-----------------------------------------紙上得來終覺淺,絕知此事要躬行 -------------------------------------------
1. [1][2][3]:《mysql高效能》第三版 baron schwarzt, peter zaitsev, vadim tkachnko 著 寧海元 周振興 彭立勛 翟衛祥 劉輝 譯
2. 博大的j**a世界:explain分析sql語句欄位的解釋和含義:)
3.過來啊小蓮:btree和b+tree詳解:
mysql 優化 聚集索引 mysql 索引優化
一.聚集索引 clustered index innodb預設依據主鍵列聚集,myisam不使用 特點 b樹每個葉子包含實際資料行,資料按照索引順序地儲存在物理頁上。優點 1.範圍查詢,獲取指定id的全部資料只需從磁碟讀取少量資料頁 如果不使用聚集索引,每條資料可能引起一次磁碟io。2.由於索引和資...
mysql索引優化原則 MySQL 索引優化原則
索引優化原則 1 最左字首匹配原則,聯合索引,mysql會從做向右匹配直到遇到範圍查詢 3 and d 4 如果建立 a,b,c,d 順序的索引,d是用不到索引的,如果建立 a,b,d,c 的索引則都可以用到,a,b,d的順序可以任意調整。2 和in可以亂序,比如a 1 and b 2 and c ...
mysql索引優化原則 MySQL索引優化
mysql官方對索引的定義 索引是幫助mysql高效獲取資料的資料結構。索引是在儲存引擎中實現的,所以每種儲存引擎中的索引都不一樣。如myisam和innodb儲存引擎只支援btree索引 memory和heap儲存引擎可以支援hash和btree索引。這裡僅針對常用的innodb儲存引擎所支援的b...