2014-09-05 185 views
0

我需要從「最新」(即最高記錄ID)記錄中獲取每個字段值(本例中爲server_name)的值。MySQL優化需要說明

我已經在server_nameid上添加了server_name_id索引。

我的第一次嘗試需要幾分鐘的時間才能運行。

SELECT server_name, state 
FROM replication_client as a 
WHERE id = (
    SELECT MAX(id) 
    FROM replication_client 
    WHERE server_name = a.server_name) 
ORDER BY server_name 

我的第二次嘗試花了0.001秒跑。

SELECT rep.server_name, state FROM (
    SELECT server_name, MAX(id) AS max_id 
    FROM replication_client 
    GROUP BY server_name) AS newest, 
replication_client AS rep 
WHERE rep.id = newest.max_id 
ORDER BY server_name 

此優化背後的原理是什麼? (我希望能夠在沒有反覆試驗的情況下編寫優化查詢。)

P.S.說明如下:

mysql> EXPLAIN 
    -> 
    -> SELECT server_name, state 
    -> FROM replication_client as a 
    -> WHERE id = (SELECT MAX(id) FROM replication_client WHERE server_name = a.server_name) 
    -> ORDER BY server_name 
    -> ; 
+----+--------------------+--------------------+------+----------------+----------------+---------+-------------------+--------+-----------------------------+ 
| id | select_type  | table    | type | possible_keys | key   | key_len | ref    | rows | Extra      | 
+----+--------------------+--------------------+------+----------------+----------------+---------+-------------------+--------+-----------------------------+ 
| 1 | PRIMARY   | a     | ALL | NULL   | NULL   | NULL | NULL    | 630711 | Using where; Using filesort | 
| 2 | DEPENDENT SUBQUERY | replication_client | ref | server_name_id | server_name_id | 18  | mrg.a.server_name | 45050 | Using index     | 
+----+--------------------+--------------------+------+----------------+----------------+---------+-------------------+--------+-----------------------------+ 

mysql> explain 
    -> SELECT rep.server_name, state FROM (
    ->  SELECT server_name, MAX(id) AS max_id 
    ->  FROM replication_client 
    ->  GROUP BY server_name) AS newest, 
    -> replication_client AS rep 
    -> WHERE rep.id = newest.max_id 
    -> ORDER BY server_name 
    -> ; 
+----+-------------+--------------------+--------+---------------+----------------+---------+---------------+------+---------------------------------+ 
| id | select_type | table    | type | possible_keys | key   | key_len | ref   | rows | Extra       | 
+----+-------------+--------------------+--------+---------------+----------------+---------+---------------+------+---------------------------------+ 
| 1 | PRIMARY  | <derived2>   | ALL | NULL   | NULL   | NULL | NULL   | 2 | Using temporary; Using filesort | 
| 1 | PRIMARY  | rep    | eq_ref | PRIMARY  | PRIMARY  | 4  | newest.max_id | 1 |         | 
| 2 | DERIVED  | replication_client | range | NULL   | server_name_id | 18  | NULL   | 15 | Using index for group-by  | 
+----+-------------+--------------------+--------+---------------+----------------+---------+---------------+------+---------------------------------+ 

回答

2

好了,整個事情是相當自我解釋,當你在你的第一個解釋計劃一下兩個詞:DEPENDENT SUBQUERY

這意味着,對於每一行,你where狀態檢,子查詢被執行。當然這可以像地獄一樣緩慢。

另請注意,執行查詢時有一個操作順序。

FROM clause 
WHERE clause 
GROUP BY clause 
HAVING clause 
ORDER BY clause 
SELECT clause 

當你可以在FROM條款進行篩選,這比在WHERE條款過濾功能更好地...

+0

謝謝,這是一個很好的解釋。 – fadedbee 2014-09-05 10:51:22