[英]Entity Framework queries miss filtered index WHERE BIT field = 0
我注意到Entity Framework使用負布爾過濾器轉換LINQ查詢,這樣生成的查詢計划就不會使用過濾索引。 例如,查詢:
context.Foo.Count(f => !f.IsActive)
生成SQL語句:
SELECT
[GroupBy1].[A1] AS [C1]
FROM ( SELECT
COUNT(1) AS [A1]
FROM [dbo].[Foos] AS [Extent1]
WHERE [Extent1].[IsActive] <> cast(1 as bit)
) AS [GroupBy1]
注意WHERE
子句使用[IsActive] <> cast(1 as bit)
,而不是更直觀的[IsActive] = 0
。 使用篩選索引時,這會成為問題。 上述查詢的計划不會使用以下索引:
CREATE INDEX IX_Foo_IsActive ON Foos (IsActive) WHERE (IsActive = 0)
我懷疑EF以這種方式生成查詢的原因與DB null語義有關,但即使使用不可空的位字段也會發生這種情況。 我已經驗證用EF的語法( IsActive <> 1
)編寫過濾的索引可以解決問題,但是這會破壞使用更常見語法的任何非EF查詢。
有更好的解決方法嗎?
這里有完整的示例程序: http : //dotnetfiddle.net/3kZugt 。 上面使用的實體類型是:
public class Foo
{
public int Id { get; set; }
public bool IsActive { get; set; }
}
出於某種奇怪的原因,有時候我們看不到一些非常明顯的東西並不常見:將數據庫謂詞直接轉換為C#謂詞,即
WHERE IsActive = 0
被翻譯成
f => f.IsActive = false
你必須停止在C#中思考並開始在SQL中思考;)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.