2012-03-26 155 views
3

我有一張包含100萬條記錄的表,我設計了2個查詢。SQL查詢性能差異

表索引:

id = primary 
bedroom = index 
elevator = index 
pricemeter = index 
dateadd = index 

我想知道,爲什麼這個查詢:

SELECT 
    * 
FROM (
    SELECT 
     * 
    FROM `p_apartmentbuy` 
    WHERE 
     `sqm` > 100 
     AND `bedroom` > 1 
     AND `elevator` = 1 
     AND `pricemeter` < 5999999 
    ORDER BY `id` DESC 
    LIMIT 0, 30 
) AS `alias` 
ORDER BY `id` DESC, `dateadd` DESC 

是如此速度遠遠這一個:

SELECT 
    * 
FROM `p_apartmentbuy` 
WHERE 
    `sqm` > 100 
    AND `bedroom` > 1 
    AND `elevator` = 1 
    AND `pricemeter` < 5999999 
ORDER BY `id` DESC, `dateadd` DESC 
LIMIT 0, 30 

首先查詢了0.0027秒,第二個查詢耗時5.6848秒。 這兩個結果都與其他相同,where子句中的變量都是示例。

解釋快速查詢: enter image description here

解釋慢查詢: enter image description here

+0

執行計劃說什麼? – Lamak 2012-03-26 14:40:17

+2

在SELECT之前使用'EXPLAIN',這樣我們就可以看到執行計劃並確保你的SQL緩存在運行查詢前是空的。 – 2012-03-26 14:42:09

+0

@ N.B。我加了解釋結果 – Hamidreza 2012-03-26 14:51:10

回答

2

那麼,我們需要更多關於索引的信息,但簡單看一下這些查詢表明它們是不同的。他們也可能會得出不同的結果,這只是一個巧合,他們是相同的(最可能取決於數據的結構)。在第一個查詢中,您選擇了30行,按id(可能有索引)排序,然後按dateadd排序它們,這非常簡單。您的第二個查詢必須按照這兩列對所有百萬條記錄進行排序,然後選擇30,因此顯然會更加昂貴。

+1

第一個查詢還應該通過'id'對所有百萬條記錄進行排序,並且索引應該只在過濾中發揮作用,而不是排序。唯一可能導致這種情況的是內部的'dateadd'排序,因爲正如你所建議的那樣,它排列了許多行中的兩列,而不是一列。 – vol7ron 2012-03-26 15:42:44

0

您的表必須使用ID作爲主鍵。在這種情況下,行使用ID列進行索引,並且所有數據已按ID排序。

因此,採取前30行是快速的MySQL計劃。那麼訂購這30行將會很快。

第二個查詢必須返回所有行才能根據'dateadd'列進行排序。 LIMIT子句將被計算。

我希望這能回答你的問題。

+0

ID是主鍵,where子句中的所有字段都被索引爲 – Hamidreza 2012-03-26 14:53:40

2

第二個查詢必須將整個數據集按iddateadd排序,然後才能應用限制。

另一方面,第一個查詢只返回30條記錄,然後按iddateadd排序。更少的工作。

+0

+1,但第一個查詢按'id'排序,而不是'dateadd' – vol7ron 2012-03-26 14:45:30

+0

最終結果按'dateadd'排序。我正在談論這兩個查詢作爲整體:) – 2012-03-26 14:46:49

+0

您可能想要更改我的編輯,但我覺得很困惑,因爲上面的第二個查詢按'id'和'dateadd'排序,第一個查詢首先按'id',然後限制,然後剩下的30個分配給'id'和'dateadd'。 – vol7ron 2012-03-26 15:13:15

1

解釋將確認

但第一個是由ID,這大概是主鍵,所以通過ID順序不需要排序得到的前30條記錄。然後排序只是那些30

而第二個,越來越所有記錄中沒有順序,然後按編號和日期對它們進行排序,然後承擔DATEADD第30 ...

指數,也許?

只有受過教育的猜測。