假設我有一個包含100列和100萬行的訂單表。它在OrderID和FK約束StoreID - > Store.StoreID上有一個PK。上述爲什麼在MySQL中查詢需要很長時間,即使有LIMIT子句?
1)select * from 'Order' order by OrderID desc limit 10;
需要幾毫秒。
2)select * from 'Order' o join 'Store' s on s.StoreID = o.StoreID order by OrderID desc limit 10;
這在某種程度上可能需要長達許多秒。我添加的內部聯接越多,速度就越慢。
3)select OrderID, column1 from 'Order' o join 'Store' s on s.StoreID = o.StoreID order by OrderID desc limit 10;
這似乎加速執行起來,通過限制我們選擇列。
有幾點,我不明白在這裏,如果有人更熟悉與MySQL(或一般rmdb查詢執行)可以啓發我,真的很感激。
查詢1很快,因爲它只是一個反向查找的PK和DB只需要返回遇到的前10行。
我不明白爲什麼查詢2應該永遠採取。操作不應該一樣嗎?即通過PK得到前10行並且然後與其他表加入。由於存在FK約束,因此可以保證滿足關係。所以DB不需要加入超過必要的行數,然後修剪結果,對吧?除非FK約束允許空FK?在這種情況下,我猜左連接會比內連接快得多嗎?
最後,我猜查詢3只是更快,因爲在這些不必要的連接中使用較少的列?但爲什麼查詢執行時需要其他列加入?它不應該只是首先使用PK加入,然後獲得10列的列嗎?
謝謝!
如果你有一個有100列的表格,那麼表格的設計就會出錯。作爲一個經驗法則,RDBMS擅長使用細長的表格,只要您可以應用明智的btree索引即可。 – gview
雖然很容易指出不好的設計,但不會簡單地從頭開始編寫所有的東西,或者在獲得第一個機會時重新設計/重寫。 =) – Xerion
Xerion:事實上,指出一個糟糕的設計並不容易 - 如果是的話,會有更少的糟糕設計。它實際上需要了解關係數據庫背後的基本概念,以及有效設計模式的一些經驗。然而,我不需要那些人說,當你規定你有一個100列以上的桌子時,那種設計是完全錯誤的。我知道它可能不是你的設計,你可能無法改變它,但你也被畫到了一個角落,在這個角落裏,容易和高性能的東西都不是。 – gview