I came across an issue with EF creating terrible queries when searching on a string field. Its produced a query in the style of lazy programmers to encompass null checking which forces the whole index to be scanned.
consider the following queries.
Query 1
var p1 = "x";
var r1 = ctx.Set<E>().FirstOrDefault(
subject =>
p1.Equals(subject.StringField));
Query 2
const string p2 = "x";
var r2 = ctx.Set<E>().FirstOrDefault(
subject =>
p2.Equals(subject.StringField));
Query 1 produces
WHERE (('x' = [Extent2].[StringField]) OR (('x' IS NULL) AND ([Extent2].[StringField] IS NULL)))
and executes in 4 seconds
Query 2 produces
WHERE (N'x' = [Extent2].[StringField])
and executes in 2 milliseconds
Does anyone know of any work arounds? (no the parameter cant be a const as it is entered by user input but cannot be null.)
N.B When profiled, both queries are prepared with sp_executesql by EF; as of-cause if they were just executed the query optimiser would negate the OR 'x' IS NULL check.
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…