sql-server - 带有前导通配符的参数化查询的 SQL Server 性能

标签 sql-server sql-server-2008 parameterized

我有一个 SQL 2008 R2 数据库,其中一个表中有大约 200 万行,并且在使用参数化 SQL 时,我正在努力解决特定查询的性能问题。

在表中,有一个包含名称的字段:

[患者姓名] nvarchar NULL,

该字段还有一个简单的索引:


CREATE NONCLUSTERED INDEX [IX_Study_PatientsName] ON [dbo].[Study] 
(
    [PatientsName] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON, FILLFACTOR = 90) ON [INDEXES]
GO

当我在管理工作室中执行此查询时,执行大约需要 4 秒:


declare @StudyPatientsName nvarchar(64)
set @StudyPatientsName= '%Jones%'

SELECT COUNT(*) FROM Study WHERE Study.PatientsName like @StudyPatientsName

But, when I execute this query:


SELECT COUNT(*) FROM Study WHERE Study.PatientsName like '%Jones%'

it takes a bit more than a half second to execute.

Looking at the execution plans, the query without parameterization does an Index Scan using the above mentioned index, which obviously is efficient. The parameterized query uses the index, but does a range seek on the index.

Part of the issue is having the leading wildcard. When I remove the leading wildcard, both queries return in a fraction of a second. Unfortunately, I do need to support leading wildcards.

We have a home grown ORM that does parameterized queries where the problem originated. These queries are done based on input from a user, so parameterized queries make sense to avoid things like a SQL injection attack. I'm wondering if there's a way to make the parameterized query function as well as the non-parameterized query?

I've done some research looking at different ways to give hints to the query optimizer, trying to force the optimizer to redo the query plan on each query, but haven't found anything yet to improve the performance. I tried this query:


SELECT COUNT(*) FROM Study WHERE Study.PatientsName like @StudyPatientsName
OPTION ( OPTIMIZE FOR (@StudyPatientsName = '%Jones%'))

this 中提到了该解决方案问题,但没有什么区别。

如有任何帮助,我们将不胜感激。

最佳答案

您似乎想要强制扫描。有一个 FORCESEEK 提示,但我看不到任何类似的 FORCESCAN 提示。不过这应该可以做到。

SELECT COUNT(*) 
FROM Study 
WHERE Study.PatientsName + '' like @StudyPatientsName

尽管也许您可以对您的数据尝试以下操作,看看效果如何。

SELECT COUNT(*) 
FROM Study 
WHERE Study.PatientsName  like @StudyPatientsName
option (recompile)

关于sql-server - 带有前导通配符的参数化查询的 SQL Server 性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3495355/

相关文章:

sql - 计算sql server中的平均评分

sql-server - Analysis Services .abf 文件数据库还原

java - 参数化类型(如 Class<)的等效 C# 是什么?在 Java 中扩展 Throwable>?

java - junit参数化测试不按顺序输出结果

sql-server - SQL Server 2005 Sleep_Task 等待类型

sql-server - MSSQL 服务在 ubuntu 上启动失败

sql - 如果数据类型从smallint更改为bigInt,表的存储大小是否会扩大四倍?

java - 部署WAR文件时的Tomcat 7.0.52 JNDI错误

linux - Linux 上通过 ODBC 的 Delphi SQLConnection 无法连接到 SQL

android - UIAutomator/Espresso 中的参数化