2015-12-23 83 views
0

我正在用2個派生表(或者你可以稱之爲子查詢)和WHERE子句來寫一個查詢來篩選,但我不知道在哪裏我應該放置WHERE子句來優化性能。請看下面的例子: (我肯定知道這是一個愚蠢的例子,但它可以幫助來形容我的問題)我應該把WHERE子句放在子查詢中(派生表)嗎

SELECT * 
FROM 
    (SELECT id FROM A) A 
    JOIN 
    (SELECT id FROM B) B 
    ON A.id = B.id 
WHERE A.id = 1 

VS

SELECT * 
FROM 
    (SELECT id FROM A 
    WHERE A.id = 1 
    ) A 
    JOIN 
    (SELECT id FROM B 
    WHERE B.id = 1 
    ) B 
    ON A.id = B.id 

從性能的角度來看,它的問題在哪裏放置WHERE子句? 我的數據庫太小了,所以在測試查詢時我沒有看到任何區別。 謝謝。

+5

什麼阻止您從A.id = b.ID上的JOIN B做SELECT * WHERE A.Id = 1? – wentimo

+0

那麼,第二個甚至沒有有效的語法 – Paparazzi

+0

糾正了他。 – trincot

回答

0

測試過這個 - 頂部查詢有where子句在嵌套select之外,下部查詢在嵌套select中有where子句。這個測試是用200k行完成的。我懷疑表現的差異可以忽略不計。

enter image description here

+0

請分享用於生成執行計劃的腳本。查詢,表格定義等我期望在這些計劃之間完全沒有區別。 –

+0

使用了他詢問的確切疑問,我認爲這很明顯。 –

1

既不如果能避免它
似乎沒有要在需要派生
這個例子特定需要您做出更復雜的好像查詢優化器有更多的機會不最好的事情

這僅僅是一個真正瘋狂的查詢,但

SELECT A.id 
FROM A 
JOIN B 
     on A.id = B.ID 
    and A.id = 1 

SELECT A.id FROM A where A.Id = 1 
intersection 
SELECT B.id FROM B where B.Id = 1 

如果你打算做一個派生的話,那麼我通常會從where派生出來。發生在你身上的事情是,在複雜的查詢中,優化器會變得愚蠢,並且會發生一堆循環連接。如果它變得愚蠢並且執行一堆循環,你甚至可能最終將子實體化爲#temp。

+0

派生表不會「殺死索引」 - 容易讓您自己測試。 –

+0

謝謝兄弟。我絕對知道這個查詢是瘋了,但我只是試圖用這個愚蠢的例子來描述我的問題。我正在處理的真實查詢要複雜得多,並且會讓每個人都確信。 :) –

+0

我通常會從where中導出。發生在你身上的事情是,在複雜的查詢中,優化器會對你產生愚蠢的感覺,並進行一堆循環連接。如果它變得愚蠢並且執行一堆循環,你甚至可能最終將實現物化爲#temp。 – Paparazzi