2014-03-04 45 views
2

我想優化一個我創建的mysql表上的查詢。我預計表格中會有很多行。看看this question接受的答案和最高投票答案表明兩種不同的方法。 我寫了這兩個查詢,並想知道哪一個更高性能。在MySQL中比較兩個查詢的性能

SELECT uv.* 
FROM UserVisit uv INNER JOIN 
    (SELECT ID,MAX(visitDate) visitDate 
    FROM UserVisit GROUP BY ID) last 
    ON (uv.ID = last.ID AND uv.visitDate = last.visitDate); 

EXPLAIN產量運行此:

+----+-------------+------------+--------+---------------+---------+---------+--------------------------------+------+-------------+ 
| id | select_type | table  | type | possible_keys | key  | key_len | ref       | rows | Extra  | 
+----+-------------+------------+--------+---------------+---------+---------+--------------------------------+------+-------------+ 
| 1 | PRIMARY  | <derived2> | ALL | NULL   | NULL | NULL | NULL       | 2 |    | 
| 1 | PRIMARY  | uv   | eq_ref | PRIMARY  | PRIMARY | 11  | last.playscanID,last.visitDate | 1 |    | 
| 2 | DERIVED  | UserVisit | index | NULL   | PRIMARY | 11  | NULL       | 4 | Using index | 
+----+-------------+------------+--------+---------------+---------+---------+--------------------------------+------+-------------+ 
3 rows in set (0.01 sec) 

而其他查詢:

SELECT lastVisits.* 
FROM (SELECT * FROM UserVisit ORDER BY visitDate DESC) lastVisits 
GROUP BY lastVisits.ID 

運行與EXPLAIN產量:

+----+-------------+------------+------+---------------+------+---------+------+------+---------------------------------+ 
| id | select_type | table  | type | possible_keys | key | key_len | ref | rows | Extra       | 
+----+-------------+------------+------+---------------+------+---------+------+------+---------------------------------+ 
| 1 | PRIMARY  | <derived2> | ALL | NULL   | NULL | NULL | NULL | 4 | Using temporary; Using filesort | 
| 2 | DERIVED  | UserVisit | ALL | NULL   | NULL | NULL | NULL | 4 | Using filesort     | 
+----+-------------+------------+------+---------------+------+---------+------+------+---------------------------------+ 
2 rows in set (0.00 sec) 

我不確定如何解釋兩個EXPLAIN的結果。
哪些查詢可以期待更快,爲什麼?

編輯: 這是正路UserVisit表如下:

+----------------+---------------------+------+-----+---------+-------+ 
| Field   | Type    | Null | Key | Default | Extra | 
+----------------+---------------------+------+-----+---------+-------+ 
| ID    | bigint(20) unsigned | NO | PRI | NULL |  | 
| visitDate  | date    | NO | PRI | NULL |  | 
| visitTime  | time    | NO |  | NULL |  | 
| analysisResult | decimal(3,2)  | NO |  | NULL |  | 
+----------------+---------------------+------+-----+---------+-------+ 
4 rows in set (0.00 sec) 
+0

從技術上講,第二個查詢不能可靠地返回你尋求的答案。實際上,到目前爲止,它在所有版本(支持子查詢)中都可用。在實踐中,它很少超過第一個查詢。 – Strawberry

+0

@Strawberry你能詳細解釋爲什麼第二個查詢無法可靠地返回正確答案嗎?是否因爲不能保證最頂行將被GROUP BY選中?另外,你能否解釋爲什麼這些查詢的性能差別不大? –

+1

準確地說 - 儘管如我所說,在實踐中它總是這樣做 - 並且(作爲魔鬼的支持者一分鐘)內維爾K的論點有些虛假,因爲在將來的版本中,所有類型的東西都會改變。我更願意堅持第二個解決方案無證的界限(除非您在手冊中統計相關頁面的評論部分)。我對MySQL的機制知之甚少(讀「什麼」),以說明爲什麼性能差異可以忽略不計,但我已經測試了大量(索引)表上的兩個查詢。儘管肯定與NK有關複合鍵的觀點一致。 – Strawberry

回答

1

首先,你可能需要閱讀說明manual。這是一個密集的閱讀。但它應該提供你想要的大部分信息。其次,正如草莓所說,第二個查詢是偶然發生的。行爲可能會在將來的版本中發生變化,並且您的查詢不會返回錯誤,只是不同的數據。這幾乎總是一件壞事...

最後,說明版本1會更快。在EXTRA中,它是說它使用了一個索引,它比filesort快得多。如果沒有模式,很難確定,但我認爲您還可以從ID和visitdate上的複合鍵中受益。