簡體   English   中英

左聯接或選擇中選擇(SQL-查詢速度)

[英]Left join or Select in select (SQL - Speed of query)

我有這樣的事情:

SELECT CompanyId 
FROM Company
WHERE CompanyId not in
    (SELECT CompanyId 
     FROM Company 
     WHERE (IsPublic = 0) and CompanyId NOT IN 
         (SELECT ShoppingLike.WhichId 
          FROM Company 
          INNER JOIN 
          ShoppingLike ON Company.CompanyId = ShoppingLike.UserId 
          WHERE (ShoppingLike.IsWaiting = 0) AND
                (ShoppingLike.ShoppingScoreTypeId = 2) AND
                (ShoppingLike.UserId = 75)
          )
     )

它具有3個選擇,我想知道如何不進行3個選擇就擁有它,而哪一個具有100萬條記錄的更快速度? “選擇中選擇”還是“左聯接”?

我的經驗來自Oracle。 優化棘手的查詢從來沒有正確的答案,這是您和優化人員之間的協作。 您通常需要在編寫查詢的每個階段檢查解釋計划,有時還要查找跟蹤,以找出最優化的思路。 話說回來:

  • 您可以通過將子查詢WHERE子句的全部內容放在NOT( ... )來刪除外部SELECT 從表面上看,它將阻止對公司(或公司ID的索引)進行外部全面掃描。 嘗試一下,檢查輸出是否相同並獲取計時,然后在嘗試以下操作之前暫時將其刪除。 由於創建了隱式OR, NOT()可能會導致優化器停止考慮針對ShoppingLike子查詢的ANTI-JOIN。
  • 確保將CompanyId和WhereId定義為NOT NULL列。 沒有這個(或類似的顯式CompanyId IS NOT NULL ),則通常會丟棄ANTI-JOIN選項。
  • 最內部的子查詢不相關(不引用外部查詢中的任何內容),因此可以分別提取和調整。 作為樣式問題,我希望您先掃描ShoppingLike,然后圍繞INNER JOIN交換表名,因為它具有針對它的所有過濾器。 它不會有任何區別,但它讀起來更容易,並且可以使用提示以指定的順序掃描表。 我什至會質疑此子查詢中是否需要Company表。
  • 當非常相似的NOT EXISTS有時為優化器提供更多/替代選項時,您就使用了NOT IN

除非您開始嘗試解釋計划,否則以上所有內容都是反復試驗。 Oracle可以順其自然,在LEFT JOININ SELECT之間進行轉換。 1M +行將為投資創造時間。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM