2015-04-15 15 views
1

我根據是否設置了變量來篩選表格。但是聚集索引沒有被使用。是否有可能讓查詢以某種方式使用索引。 (我不能動態地創建在這種情況下,查詢)根據變量和使用指數篩選表格

DECLARE @UseFilter as bit = 1 

select pkEventId from EventEvent 
where pkEventID = 57637 or @UseFilter = 0 

執行計劃(不使用索引)
enter image description here

如果我跳過Or使用的索引。

select pkEventId from EventEvent 
where pkEventID = 57637 

執行計劃(使用索引)
enter image description here

+0

你做一個'IF @UseFilter = 0',使2個不同的查詢 – ughai

+0

@ughai在這種情況下,我不能這樣做,要麼。 – Magnus

+0

當@ UserFilter設置爲1時,部件'或@UseFilter = 0'應該沒有意義。@UserFilter設置爲0時執行計劃是什麼? 也許試試'WHERE pkEventID CASE WHEN @UseFilter = 0 THEN 57637 ELSE IS NOT NULL END'(從名稱猜測它不可爲空) –

回答

1

優化or是很難的,因爲你的例子顯示。解決這個問題的一個方法是使用動態SQL。您也可以試試這個:

DECLARE @UseFilter as bit = 1 

select pkEventId 
from EventEvent 
where pkEventID = 57637 
UNION ALL 
select pkEventId 
from EventEvent 
where pkEventID <> 57637 AND @UseFilter = 0; 

由於常數的比較,第二個子查詢可能會短路。

編輯:

這個版本可能會做你真正想要的:

select pkEventId 
from EventEvent 
where pkEventID = 57637 AND @UseFilter = 1 
UNION ALL 
select pkEventId 
from EventEvent 
where @UseFilter = 0; 
+0

感謝您的回答。看起來union之後的查詢沒有使用索引。 – Magnus

+0

'pkEventID <> 57637 AND'是錯誤的,它應該選擇所有行,如果'@UseFilter = 0' –

+0

@Aツ。 。 。這是一個「union all」查詢。這些由第一個子查詢檢索。 Magnus,第二部分減慢了查詢速度嗎?問題是,由於條件不變,引擎是否會短路掃描表格。 –

0

enter image description here

正如你可以看到我的索引掃描Clustered

這裏是我的Table_1創建腳本:

CREATE TABLE [dbo].[Table_1](
    [col1] [bigint] IDENTITY(1,1) NOT NULL, 
    [col2] [varchar](50) NULL, 
    [col3] [nvarchar](max) NULL, 
CONSTRAINT [PK_Table_1] PRIMARY KEY CLUSTERED 
(
    [col1] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY] 
+0

是的,但它正在掃描而不是尋找。 – Magnus