在MySQL數據庫中索引的優化是最重要的優化手段之一,能夠解決生產過程中的大部分SQL性能問題。在對MySQL數據庫優化的時候,對系統進行基於索引的梳理,這個動作是最有效的操作。創建唯一性索引,加快數據的檢索速度。通過索引訪問表的時候,一般的索引高度不會超過4,對於葉子節點來說,訪問的葉子也不多,因爲索引都是在某一個列上,葉子裏面會有很多的索引值,很多時候,索引都在內存中,所以提取數據的速度會比較快,但是這裏面也有一個問題,就是insert buffer問題,會出現訪問一個索引的時候,導致索引頁產生merge(合併)。還有一個缺點,通過索引跳轉到數據頁上的時候,這個是很消耗資源的,這個成本可能會很高,如果不高的話,前提是索引的順序和表的順序很一致。
對於MySQL來說,索引的insert會帶來分裂、合併,MySQL會智能地根據insert數據的走向(遞增、遞減、隨機數)來判斷分裂(中間分裂、左分裂、右分裂)。如果索引建的太多的話,葉子、分支、根要分裂,這也要消耗資源,根和分支分裂的情況還是比較少的,葉子的分裂會比較頻繁。
(1)索引優化
查看索引使用情況
show indexes from order_info;
結果:
“Handler_read%”顯示狀態檢查索引的使用;
show status like 'Handler_read%';
Handler_read_key的值表示索引被使用的次數,代表性能得到改善了。
Handler_read_rnd_next的值表示讀下一行的請求數,代表正在進行表掃描,性能不好需要建立索引。
(2)高性能的索引策略
1.主鍵或者唯一索引的性能比普通索引好
2.複合索引比普通索引的性能更好
3.cardinality(基數)小的列不要建獨立索引
4.長字段的列使用部分索引比全部的好
5. 常用的搜索和排序字段(按索引排序避免,這種優化的概念必須清楚)需要索引
6.join列的類型要保持一致並創建索引
7.索引的數量要適中,少了和多了都會影響性能
8.生產繁忙的時候,不要建立索引,因爲會非常消耗物理IO
使用optimize table 對刪除數據的表空間進行碎片合併:
optimize table order_info;
常用的SQL優化:
(1)針對大批量插入數據優化方案
下面從兩種應用情況分析一下大批量插入數據優化方案:
對於MyIsam存儲引擎表的非空表來說,關閉非唯一索引的更新,對於空表來說,先導入數據然後創建索引。
對於InnoDB存儲引擎表來說,在導入數據前關閉唯一性校驗:SET UNIQUE_CHECKS=0,關閉自動提交:SET AUTOCOMMIT=0,將導入的數據按照主鍵的順序排序,導入結束後再打開唯一性校驗和自動提交:SET UNIQUE_CHECKS=1。
(2)優化insert語句
下面從5個方面分析插入語句的優化:
1.如果相同用戶插入了很多的值,嘗試使用多個值語句插入,從而降低了客戶機和數據庫之間的連接。
例:insert into test values(1,2)(1,3)(1,4)…
2.使用 INSERT DELAYED 語句可以是insert的速度得到提升,但是當表被上了寫鎖和使用alter table對錶結構進行修改的時候就不管用了。
數據存放在內存隊列,沒有真正寫入磁盤,比分條插入要快很多,LOW_PRIORITY則剛好相反
3.將索引、數據文件分別放在不同的磁盤上
4.對於MyISAM表中,當散裝插入,增加bulk_insert_buffer_size的值,以增加的速度。
5.當從文件加載的表時,LOAD DATA INFILE通常比插入快20倍。
(3)優化order by語句
MySQL數據庫中的兩種排序方式:
一是通過索引的順序掃描直接返回有序的數據,不需要額外的排序,效率較高。
二是通過對返回的數據進行排序(filesort排序)。
對於filesort的優化:通過創建合適的索引減少filesort的出現,但不可避免的情況下,應優化。的掃描算法排序時,其選擇一個更高的存儲器開銷,但具有比輔助掃描算法更高的分選效率。
注意:
1.MySQL通過query語句取出的字段總大小判斷使用哪種算法
2.如果長度大於max_length_for_sort_data較小,則第二算法被使用,否則所述第一類型被採用。
3.適當增加這個參數的值,你可以讓MySQL的選擇更好的排序算法,但如果設置得太高,就會導致低CPU使用率和高磁盤IO。
4.適當增大sort_buffer_size的大小,避免使用臨時表進行磁盤排序,但是注意該參數是每個會話的,不能過大
5.儘量使用必要字段,而不是使用 SELECT * ,減少排序區的使用,提高SQL性能
(4)優化group by語句
1.默認情況下,所有的group by都要進行排序。
2.如果顯示的包含了一個相同列的ORDER BY子句,則對性能影響不大。
3.如果想要避免排序結果的消耗,可以指定ORDER BY NULL禁止排序。
(5)優化嵌套查詢
1.子查詢可以節省很多步驟完成SQL操作。
2.子查詢可以避免事務或者死鎖,並且寫起來很容易。
3.但有些情況下使用連接join查詢的效率更高一些,join不需要創建臨時表。
(6)MySQL怎麼優化or
1.對於包含OR的查詢語句,如果要使用索引,那麼OR之間的每個條件列都必須用到索引。
2.如果OR的前後列是複合索引,那麼不會走索引。
3.可以考慮適當添加索引。
(7)優化分頁查詢
在分頁取數據的時候,每一次換頁都執行一次select語句。針對這種情況做些優化:
首先,排序的指數分頁操作,然後檢索數據回到談判桌前。最好的情況是直接使用的綜合指數,而無需返回表。
其次增加一個用來記錄上一頁最後一行id號的參數last_page_record。
(8)使用SQL提示
1.使用索引,查詢語句表的名稱後,請提供您希望MySQL參考指標,這時候MySQL不會考慮其他指標。
2.忽略索引,查詢語句表的名稱後,請提供您希望MySQL忽略了索引,所以MySQL將忽略指定索引。
3.FORCE INDEX,這迫使MySQL使用一個特定的指數,可以使用FORCE INDEX作爲查詢提示。
4.對於MyISAM存儲引擎表,可以使用select SQL_BUFFER_RESULTS * FROM 一個表強制MySQL生成一個臨時的結果集,這個動作將釋放表的所有的鎖。