1. 程式人生 > 實用技巧 >18. SQL優化

18. SQL優化

1 優化SQL語句的一般步驟

1.1 通過 show status命令瞭解各種SQL的執行頻率

​ MySQL客戶端連線成功後,通過show[session|global]status命令可以提供伺服器狀態資訊

# 所有儲存引擎的表統計資訊
show status like 'Com_%';
# InnoDB相關的表統計資訊
show status like 'Innodb_%';
# 檢視資料庫基本情況
# Connections:試圖連線 MySQL 伺服器的次數。 
# Uptime:伺服器工作時間。 
# Slow_queries:慢查詢的次數。
show status like 'Connections|Uptime|Slow_queries';

Com_xxx 表示每個 xxx 語句執行的次數,我們通常比較關心的是以下幾個統計引數。

  • Com_select:執行 select 操作的次數,一次查詢只累加 1。
  • Com_insert:執行 INSERT 操作的次數,對於批量插入的 INSERT 操作,只累加一次。
  • Com_update:執行 UPDATE 操作的次數。
  • Com_delete:執行 DELETE 操作的次數。

1.2 定位執行效率低的SQL語句

1.3 通過EXPLAIN分析低效率SQL的執行計劃

通過 EXPLAIN 或者 DESC 命令獲取 MySQL如何執行 SELECT 語句的資訊,包括在 SELECT 語句執行過程中表如何連線和連線的順序。

1.4 確定問題並採取相應的優化措施

如果經過上述步驟已經分析出問題出現的原因,此時使用者可以根據情況進行相應的優化。

比如全表掃描導致查詢效率低可以考慮新增索引。

2 索引問題

2.1 索引的儲存分類

MyISAM 儲存引擎的表的資料和索引是自動分開儲存的,各自是獨立的一個檔案;InnoDB儲存引擎的表的資料和索引是儲存在同一個表空間裡面,但可以有多個檔案組成。

MySQL 中索引的儲存型別目前只有兩種(BTREE 和 HASH),具體和表的儲存引擎相關:MyISAM 和 InnoDB 儲存引擎都只支援 BTREE 索引;MEMORY/HEAP 儲存引擎可以支援 HASH和 BTREE 索引

2.2 MySQL如何使用索引

1、使用索引

(1)多列索引,最左原則,查詢的條件中用到了最左邊的列,索引一般就會使用。

(2)like查詢,後面如果是常量並且只有%號不在第一個字元,索引才可能被使用。

(3)如果對大的文字進行搜尋,使用全文索引而不用使用 like ‘%…%’。

2、存在索引但不使用索引

(1)如果 MySQL 估計使用索引比全表掃描更慢,則不使用索引。例如如果列key_part1 均勻分佈在 1 和 100 之間,下列查詢中使用索引就不是很好:

SELECT * FROM table_name where key_part1 > 1 and key_part1 < 90;

(2)or分割開的條件,如果or前的條件的列中有索引,而後面的列中沒有索引,那麼涉及到的索引都不會被用到。

(3)like後面的值以%開頭

(4)如果列型別是字串,那麼一定記得在 where 條件中把字元常量值用引號引起來,否則的話即便這個列上有索引,MySQL 也不會用到的。

2.3 檢視索引使用情況

如果索引正在工作,Handler_read_key 的值將很高,這個值代表了一個行被索引值讀的次數,很低的值表明增加索引得到的效能改善不高,因為索引並不經常使用。 Handler_read_rnd_next 的值高則意味著查詢執行低效,並且應該建立索引補救。這個值的含義是在資料檔案中讀下一行的請求數。如果正進行大量的表掃描,Handler_read_rnd_next的值較高,則通常說明表索引不正確或寫入的查詢沒有利用索引,具體如下。

mysql> show status like 'Handler_read%'; 
+-----------------------+-------+ 
| Variable_name         | Value | 
+-----------------------+-------+ 
| Handler_read_first    | 0     | 
| Handler_read_key      | 5     | 
| Handler_read_next     | 0     | 
| Handler_read_prev     | 0     | 
| Handler_read_rnd      | 0     | 
| Handler_read_rnd_next | 2055  | 
+-----------------------+-------+

3 兩個簡單實用的優化方法

3.1 定期分析表和檢查表

analyze table tb1_name[,tb2_name]...
check table tb_name...;

3.2 定期優化表

優化表的語法如下:

OPTIMIZE [LOCAL | NO_WRITE_TO_BINLOG] TABLE tbl_name [, tbl_name] ...

如果已經刪除了表的一大部分,或者如果已經對含有可變長度行的表(含有 VARCHAR、BLOB 或 TEXT 列的表)進行了很多更改,則應使用 OPTIMIZE TABLE 命令來進行表優化。這個命令可以將表中的空間碎片進行合併,並且可以消除由於刪除或者更新造成的空間浪費,但OPTIMIZE TABLE 命令只對 MyISAM、BDB 和 InnoDB 表起作用。

ANALYZE、CHECK、OPTIMIZE 執行期間將對錶進行鎖定,因此一定注意要在資料庫不繁忙的時候執行相關的操作。

4 常用SQL的優化

搜尋資料瞭解,

USE INDEX(index_name...);
IGGNORE INDEX(index_name...);
FORCE INDEX(index_name...);