2010-05-06 149 views
14

避免嵌套查詢有多重要。避免嵌套查詢

我一直學會避免他們像瘟疫一樣。但他們對我來說是最自然的事情。當我設計查詢時,我寫的第一件事就是嵌套查詢。然後我將它轉換爲連接,有時需要很長時間才能正確連接。並且很少給出大的性能改進(有時它會)

所以他們真的很糟糕。有沒有辦法使用沒有臨時表和文件的嵌套查詢

+1

我也想知道這一點。 – IsmailS 2010-05-06 06:05:47

+1

我至少在MS SQL Server中對所有性能表現都表示懷疑。 MySQL不太聰明...... – Thorarin 2010-05-06 06:09:18

回答

6

這要看,我就在那裏我使用子查詢改善一些查詢的情況。

,我知道的因素有:

  • 如果子查詢使用從外部查詢字段用於比較或不(correlated與否)
  • 如果外部查詢和子查詢之間的關係被覆蓋索引
  • 如果在連接上沒有可用索引並且子查詢不相關並返回小結果,則使用它可能會更快
  • 我還遇到了將使用order by的查詢轉換爲水性uery不使用它,不是把它變成一個簡單的子查詢和排序是改善MySQL的性能

無論如何,這是一件好事,以測試不同的變體(與SQL_NO_CACHE請),並轉相關查詢到連接的一個好的做法。

我甚至會說這是一個非常有用的做法。

如果相關查詢是您首先想到的,但您並不是主要根據集合操作進行思考,但主要是從程序操作和處理關係數據庫的角度來看,它可能是非常有用的充分採用數據模型的設定視角和轉換。

編輯: 程序VS關係
在VS程序組操作思維歸結爲等值的一些集代數表達式,例如在工會的選擇等同於選擇的工會。兩者沒有區別。
但是,當比較兩個過程時,比如將選擇標準應用於聯合的每個元素並進行聯合,然後應用選擇時,這兩者是截然不同的過程,它們可能具有非常不同的屬性(例如CPU利用率,I/O,內存)。

關係數據庫背後的想法是,你不要試圖描述如何得到結果(過程),但只是你想要的,並且數據庫管理系統將決定完成你的最佳路徑(過程)請求。這就是爲什麼SQL被稱爲4th generation language (4GL)

幫助你做到這一點的技巧之一是提醒自己,元組沒有固有的順序(set元素是無序的)。 另一個意識到,關係代數是相當全面的,並允許將請求(需求)直接轉換爲SQL(如果您的模型的語義代表了問題空間,或換句話說,如果附加到您的表和關係的名稱的意義完成正確的,換句話說,如果你的數據庫設計的很好)。

因此,你不必思考如何,只有什麼。

就你而言,它只是優先於相關查詢,所以它可能是我沒有告訴你任何新東西,但你強調了這一點,因此評論。

我認爲,如果您完全適應將查詢從一種表單轉換爲另一種表達式(rules,如分佈性)的所有規則,那麼您不希望關聯子查詢(您會看到所有表單均等)。 (注意:上面討論了理論背景,對數據庫設計很重要;實際上上述概念有偏差 - 並非所有查詢的等價重寫都必須以快速執行,集羣主鍵確實使表在磁盤上具有繼承順序等。 ..但這些偏差只是偏差;事實並非所有等效查詢執行速度都是實際DBMS的不完善,而不是其背後的概念)

+0

你有沒有一個例子,就是「在集合操作方面思考」與「在程序操作方面」。 – Midhat 2010-05-12 07:17:57

+0

@Midhat:評論答案(編輯)。對不起,如果不是你想要的,你是否在尋找更實際的例子或上面的解釋? – Unreason 2010-05-12 08:37:36

+0

謝謝。現在好多了 – Midhat 2010-05-12 08:46:48

1

我不知道它在MySQL 5.1或5.5,但在5.0.x中看起來如何,但在5.0.x嵌套查詢通常具有可怕的性能,因爲MySQL執行每個子查詢從主查詢中獲取的行。 對於像MsSQL這樣的更成熟的數據庫,內部可以將嵌套查詢重寫爲連接,但這種情況可能並非如此,但我從來沒有使用過MsSQL,所以我不確定。

http://dev.mysql.com/doc/refman/5.0/en/rewriting-subqueries.html

它也確實在某些情況下,它不僅可能重寫查詢,而一個子查詢,但它可以更有效地利用其中的一些技術,而不是使用子查詢。 - 這是相當有趣的聲明,考慮到我到目前爲止全部子查詢使數據庫抓取。

Subqueries vs joins