1. 程式人生 > >MySQL(二) —— MySQL效能優化之 SQL語句優化

MySQL(二) —— MySQL效能優化之 SQL語句優化

          SQL語句優化

 

MySQL優化的目的

  1、避免出現頁面訪問錯誤:或由於資料庫連線超時 timeout 產生頁面5xx錯誤;或由於慢查詢造成頁面無法載入;或由於阻        塞造成資料無法提交;

  2、增加資料庫穩定性:避免由於低效查詢引起的資料庫問題;

  3、優化使用者體驗:提高頁面訪問的流暢度。

 

一、SQL語句優化

  1、使用EXPLAIN關鍵字檢測SELECT查詢,查詢SQL的執行計劃。

舉例:

EXPLAIN SELECT COUNT(1) FROM account.user_info WHERE channel='mmo_no_platform' AND serverid='5020' AND id>=8;

mysql> EXPLAIN SELECT COUNT(1) FROM account.user_info WHERE channel='mmo_no_platform' AND serverid='5020' AND id>=8;
+----+-------------+-----------+-------------+--------------------------+------------------+---------+------+------+-------------------------------------------------------------+
| id | select_type | table     | type        | possible_keys            | key              | key_len | ref  | rows | Extra                                                       |
+----+-------------+-----------+-------------+--------------------------+------------------+---------+------+------+-------------------------------------------------------------+
|  1 | SIMPLE      | user_info | index_merge | PRIMARY,channel,serverid | serverid,channel | 9,391   | NULL |   56 | Using intersect(serverid,channel); Using where; Using index |
+----+-------------+-----------+-------------+--------------------------+------------------+---------+------+------+-------------------------------------------------------------+
1 row in set (0.00 sec)

 

explain 查詢結果分析:

select_type:查詢型別

table:查詢的表

type:連線的型別。好→差:const、eq_reg、ref、range、index、ALL。

possible_keys:可能使用到的索引。若為NULL,則無可能索引;

key:實際使用的索引(主鍵)。若為NULL,則無使用索引;

key_len:使用的索引的長度。在不損失精確性的情況下,索引長度越短越好。

ref:被使用的索引的列,可能是一個常數

rows:MySQL認為必須檢查的用來返回請求資料的行數

Extra:當有 使用檔案排序 Using filesort  或者  使用臨時表 Using temporary 時,則需要優化。

 

Count() 和MAX() 的優化方法

Count(*)和Count(id)的區別:Count(*)會計入id=NULL的行數,得到的結果可能會比Count(id)的值大。

mysql> EXPLAIN SELECT MAX(createdate) FROM account.user_info;

mysql> EXPLAIN SELECT MAX(createdate) FROM account.user_info;
+----+-------------+-----------+------+---------------+------+---------+------+------+-------+
| id | select_type | table     | type | possible_keys | key  | key_len | ref  | rows | Extra |
+----+-------------+-----------+------+---------------+------+---------+------+------+-------+
|  1 | SIMPLE      | user_info | ALL  | NULL          | NULL | NULL    | NULL |  18828 | NULL  |
+----+-------------+-----------+------+---------------+------+---------+------+------+-------+
1 row in set (0.00 sec)


mysql> SELECT MAX(createdate) FROM account.user_info;
+---------------------+
| MAX(createdate)     |
+---------------------+
| 2018-11-01 14:34:39 |
+---------------------+
1 row in set (0.00 sec)

建立索引:mysql> create index createdate on account.user_info(createdate);

mysql> CREATE INDEX createdate on account.user_info(createdate);
Query OK, 0 rows affected (0.26 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> EXPLAIN SELECT MAX(createdate) FROM account.user_info;
+----+-------------+-------+------+---------------+------+---------+------+------+------------------------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra                        |
+----+-------------+-------+------+---------------+------+---------+------+------+------------------------------+
|  1 | SIMPLE      | NULL  | NULL | NULL          | NULL | NULL    | NULL | NULL | Select tables optimized away |
+----+-------------+-------+------+---------------+------+---------+------+------+------------------------------+
1 row in set (0.01 sec)

 子查詢的優化:

通常情況下,需要把子查詢優化為 join 連線查詢,但在優化時要注意關聯鍵是否有一對多的關係,要注意重複資料。可以使用distinct 關鍵字進行去重查詢。

group by 查詢的優化:避免出現使用檔案排序 Using filesort  或者  使用臨時表 Using temporary 的情況。在子查詢內部增加過濾條件,而不是在外部加過濾條件group by。

LIMIT查詢的優化:limit 常用於分頁處理,時常會伴隨Order By從句使用,因此大多時候會使用 file sorts ,這樣會造成大量的IO問題。優化方式1、使用主鍵或有索引的列進行Order By 操作;2、當只要一行資料時使用LIMIT 1

 

 

 

使用連線(JOIN)來代替子查詢(Sub-Queries)

MySQL從4.1開始支援SQL的子查詢。這個技術可以使用SELECT語句來建立一個單列的查詢結果,然後把這個結果作為過濾條件用在另一個查詢中。例如,我們要將客戶基本資訊表中沒有任何訂單的客戶刪除掉,就可以利用子查詢先從銷售資訊表中將所有發出訂單的客戶ID取出來,然後將結果傳遞給主查詢,如下所示:

 

 

  1、使用EXPLAIN關鍵字檢測SELECT查詢,查詢SQL的執行計劃。

  2、使用查詢快取優化查詢

  3、當只要一行資料時使用LIMIT 1

  4、為搜尋欄位建立索引

  5、在join表的時候使用相當型別的列,並將其索引

  6、切記不要使用ORDER BY RAND()

  7、避免使用SELECT *

  8、永遠為每張表設定一個ID主鍵

  9、使用ENUM而不是VARCHAR

  10、儘可能的不要賦值為NULL

  11、固定長度的表會更快

  12、垂直分割

  13、拆分大的DELETE或INSERT

  14、越小的列會越快

  15、選擇正確的儲存引擎

  16、小心永久連結