比方說,我有三個表格 - 用戶,服務器和付款。每個用戶可以有多個服務器,每個服務器可以有多個支付。我們還想說,我想查找最近的付款並獲取有關付款所附的服務器/客戶的信息。下面是一個查詢,可以這樣做:JOINs以奇怪的順序完成;弄亂了ORDER BY?
SELECT *
FROM payments p
JOIN customers c ON p.custID = c.custID
JOIN servers s ON s.serverID = p.serverID
WHERE c.hold = 0
AND c.archive = 0
ORDER BY p.paymentID DESC
LIMIT 10;
的問題是,當我運行此查詢我得到這個解釋一下:
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE c ref PRIMARY,hold_archive hold_archive 3 const,const 28728 Using where; Using index; Using temporary; Using filesort
1 SIMPLE p ref custID custID 5 customers.custID 3 Using where
1 SIMPLE s eq_ref PRIMARY PRIMARY 4 payments.serverID 1 Using index
的問題是,查詢需要一段時間才能運行。如果我刪除了ORDER BY,它就變成10倍。但我需要ORDER BY。這裏的EXPLAIN當我刪除ORDER BY:
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE c ref PRIMARY,hold_archive hold_archive 3 const,const 28728 Using where; Using index
1 SIMPLE p ref custID custID 5 customers.custID 3 Using where
1 SIMPLE s eq_ref PRIMARY PRIMARY 4 payments.serverID 1 Using index
因此,這裏最大的區別是,「使用臨時」和「使用文件排序」是從Extra列缺。
在這種情況下,似乎是因爲我在執行ORDER BY的列不是EXPLAIN中的第一列。
另一種觀察。如果我刪除其中一個WHERE子句(同時保留ORDER BY),它會加速類似,但我需要兩個地方。下面是一個例子的解釋:
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE p index custID,serverID PRIMARY 4 NULL 10 Using where
1 SIMPLE c eq_ref PRIMARY,hold_archive PRIMARY 4 payments.custID 1 Using where
1 SIMPLE s eq_ref PRIMARY PRIMARY 4 payments.serverID 1 Using index
這裏的ORDER BY列/是/正在/在EXPLAIN的第一列完成。但是,爲什麼MySQL重新安排表加入的順序,我怎樣才能做到這一點,所以它不這樣做?你可以強制索引在MySQL中,但它似乎不會幫助..
任何想法?
有了這樣的問題,您還需要爲所有相關表提供SHOW CREATE TABLE語句 – Strawberry
快速猜測:如果沒有ORDER BY子句,則服務器會返回符合條件的前10條記錄,一旦達到該數字就停止處理。它可能以'customer'表開始,因爲這個表上有一個過濾器,然後查找相關的'payments',然後在'servers'上查找相匹配的。工作得很好。然而,當你添加'ORDER BY'時,首先需要創建一個* all *匹配記錄的列表('c' =>'p' =>'s'),然後將'paymentID'然後從該列表中選擇從「最低」開始的前10個。 – deroby