這個問題出自一位朋友的評論。他說,當一個查詢有很多子查詢時,這是一個信號,表明數據庫有設計缺陷,必須避免。他還表示,許多書籍都表明了這一點。子查詢是否是邪惡的?
我同意部分內容,但我認爲這些查詢具有複雜的邏輯,需要大量的子查詢,或者爲了避免子查詢,查詢的物化視圖或大量數據冗餘。
那麼,子查詢的真相是什麼?他們必須總是避免嗎?他們沒有問題?他們是否指出數據庫設計缺陷?有沒有可能有一個數據庫設計,允許複雜的查詢沒有數據冗餘?
這個問題出自一位朋友的評論。他說,當一個查詢有很多子查詢時,這是一個信號,表明數據庫有設計缺陷,必須避免。他還表示,許多書籍都表明了這一點。子查詢是否是邪惡的?
我同意部分內容,但我認爲這些查詢具有複雜的邏輯,需要大量的子查詢,或者爲了避免子查詢,查詢的物化視圖或大量數據冗餘。
那麼,子查詢的真相是什麼?他們必須總是避免嗎?他們沒有問題?他們是否指出數據庫設計缺陷?有沒有可能有一個數據庫設計,允許複雜的查詢沒有數據冗餘?
不,子查詢的存在並不一定意味着數據庫架構設計不佳。
Correlated subqueries應該謹慎使用(即當內部條件引用外部條款時)。
除此之外,子查詢通常是解決問題的有用和自然的方法。我傾向於在可能的情況下使用連接而不是子查詢。
許多查詢優化器會將某些類型的子查詢轉換爲連接。
我傾向於同意你的朋友,如果你經常需要子查詢,這是一個跡象表明數據庫沒有以易於查詢的方式組織。對於規範化規則而言,這可能是完美的,但對於關於數據的常見問題卻不方便。如果是這樣,解決方案通常會創建一個視圖或中間表,以更可搜索的方式將數據集中到一起。
我也同意米奇小麥說,子查詢通常是有用的。這個問題的有用性與如何最好地組織數據以使其易於查詢的問題是正交的。
「相關子查詢」(即其中where條件取決於從包含查詢的行獲得的值的那個)將針對每行執行一次。一個不相關的子查詢(其中where條件獨立於包含的查詢)將在開始時執行一次。 SQL引擎自動進行這種區分。
子查詢可能正在執行「全表掃描」。換句話說,不使用索引並返回太多的行,以至於主查詢中的Where需要過濾掉。
通常它的優化器無法確定子查詢可以作爲連接執行,在這種情況下,它會爲表中的每條記錄執行子查詢,而不是在子查詢中將表連接到表中你在查詢。一些更「企業」的數據庫在這方面更好,但他們有時仍然會錯過它。
所以更喜歡加入子查詢來獲得更快和更精確的結果。
你的朋友的邏輯是有缺陷的。儘管SQL及其各種實現在關係模型上有點鬆散,但它缺少許多基本的關鍵字或簡寫,特別是半連接,半差異(又稱反連接)和分裂。我經常使用子查詢在SQL代碼中編寫半連接和半差異;至於除法,我不確定是否可以在不使用子查詢的情況下在單個查詢中執行!
所以我使用的子查詢是由SQL語言的可疑設計,而不是我使用的數據庫的設計。
p.s.我想知道你和/或你的朋友是否使用術語「數據庫」來表示數據庫(數據集合)和DBMS(管理數據的軟件系統)是可交換的。如果是這樣,在上下文中,你的意思是DBMS,那麼聲明「當查詢有很多子查詢時,這是DBMS有設計缺陷的'味道'」可能確實如此。
你指的是任何特定的數據庫? – ajreal
@ajreal我使用PostgreSQL,但我認爲這適用於任何RMDBS。 –