我有一个包含地址的数据库,每行一个地址。包含英国的每个地址,因此约有2800万行。其中一列是'Street',我用它来执行搜索。我在这个列上有一个非唯一的非聚集索引。
然而,我与搜索速度不一致。
select * from Postcodes where Street = 'London Road'
需要大约1秒才能运行。
select * from Postcodes where Street like'London Road%'
同样需要一秒钟。
declare @Street varchar(20) = 'London Road%'
select * from Postcodes where Street like @Street
然而,这句话虽然与第二句完全相同,却需要大约40秒才能运行。
我完全不知道造成这种速度差异的原因。有什么想法吗?
答案 0 :(得分:1)
问题是MSSQLServer无法预先知道@Street
变量中包含的内容,因此它无法在Street
列上使用索引。
如果您的陈述是:
select * from Postcodes where Street = 'London';
select * from Postcodes where Street like 'London Road%';
它可以在Street
列上使用索引,因为它知道字符串以London
开头。
如果您的陈述是:
select * from Postcodes where Street like @VariableName;
它无法使用索引,因为您可以使用此语句执行:
select * from Postcodes where Street like 'London%';
select * from Postcodes where Street like '%London%';
或VariableName
的任何其他有效值。这是预编译语句中的典型问题。
您可以做的是直接使用字符串,或者不使用参数,并将您的语句更改为TSQL中的动态SQL语句。
答案 1 :(得分:1)
如果你事先知道你将永远不会有领先的通配符,并且在SQL Server 2008上你可以尝试
declare @Street varchar(20) = 'London Road%'
SELECT * FROM
Postcodes WITH (FORCESEEK)
where Street like @Street