Sql-Server

為什麼我的執行計劃(有時)包含左連接?

  • July 6, 2016

我發現了一個類似的問題,並且知道為了查詢表格

SELECT COUNT(1)
FROM foo f
LEFT OUTER JOIN bar b ON f.Value = b.Value AND f.Value = b.Value2

要在不接觸的情況下執行bar,需要在有問題的兩列上有一個唯一索引。

事實上,到目前為止,這有效,表被定義為:

CREATE TABLE [dbo].[Foo](
   [Value] [varchar](255) NOT NULL
) ON [PRIMARY]

CREATE TABLE [dbo].[Bar](
   [Value] [varchar](1024) NULL,
   [Value2] [varchar](1024) NULL
)

CREATE UNIQUE CLUSTERED INDEX [IX] ON [dbo].[Bar]
(
   [Value] ASC,
   [Value2] ASC
)

查詢計劃不涉及bar,太好了。

在我尋找為什麼這在我編寫的某些應用程序的實際查詢中不起作用的過程中,我將那裡的查詢簡化為以下簡單的測試,並且查詢規劃器也無法將手從桌子上移開bar

WITH numbers AS (
   SELECT 1 AS i
   UNION ALL SELECT i + 1
   FROM numbers
   WHERE i < 10
)
SELECT COUNT(1)
FROM numbers n
LEFT OUTER JOIN bar b ON n.i = b.Value AND n.i = b.Value2
;

這確實觸手可及。嗯。

有任何想法嗎?為什麼查詢計劃者認為這與其他查詢有什麼不同?

(我的實際問題沒有使用這個遞歸表表達式,它實際上就像展示案例一樣,兩列上的簡單連接 - 我無法理解為什麼它不會在計數場景中單獨留下連接的表。)

我懷疑區別在於隱式轉換,這可能會妨礙您。例如,Bar如果它具有兼容的數據類型,則不會觸及:

CREATE TABLE [dbo].[Bar]
(
   [Value] int NULL,
   [Value2] int NULL
);

引用自:https://dba.stackexchange.com/questions/143117