mysql性能優化之索引優化

     在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生成一個臨時的結果集,這個動作將釋放表的所有的鎖。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章