【发布时间】:2013-11-04 10:06:47
【问题描述】:
我有这个问题:
select top 100 id, email, amount from view_orders
where email LIKE '%test%' order by created_at desc
运行时间不到一秒。
现在我想参数化它:
declare @m nvarchar(200)
set @m = '%test%'
SELECT TOP 100 id, email, amount FROM view_orders
WHERE email LIKE @m ORDER BY created_at DESC
5 分钟后,它仍在运行。对于任何其他类型的参数测试(如果我将“like”替换为“=”),它会下降到性能的第一个查询级别。
我使用的是 SQL Server 2008 R2。
我尝试过 OPTION(RECOMPILE) ,它下降到 6 秒,但仍然慢得多(非参数化查询是瞬时的)。由于这是一个我预计会经常运行的查询,因此这是一个问题。
表的列有索引,视图没有,不知道能不能有所作为。
视图连接了 5 个表:一个有 3,154,333 行(用户),一个有 1,536,111 行(订单),3 个最多有几十行(订单类型等)。搜索在“用户”表(有 3M 行)上完成。
硬编码值:
参数:
更新
我已使用SET STATISTICS IO ON 运行查询。结果如下(抱歉,我不知道怎么读):
硬编码值:
表“货币”。扫描计数 1,逻辑读取 201。
表“订单状态”。扫描计数 0,逻辑读取 200。
表“付款”。扫描计数 1,逻辑读取 100。
表“礼物”。扫描计数 202,逻辑读取 404。
表“订单”。扫描计数 95,逻辑读取 683。
表“用户”。扫描计数 1,逻辑读取 7956。
参数:
表“货币”。扫描计数 1,逻辑读取 201。
表“订单状态”。扫描计数 1,逻辑读取 201。
表“付款”。扫描计数 1,逻辑读取 100。
表“礼物”。扫描计数 202,逻辑读取 404。
表“用户”。扫描计数 0,逻辑读取 4353067。
表“订单”。扫描计数 1,逻辑读取 4357031。
更新 2
此后我看到了“强制索引使用”提示:
SELECT TOP 100 id, email, amount
FROM view_orders with (nolock, index=ix_email)
WHERE email LIKE @m
ORDER BY created_at DESC
不确定它是否会起作用,我不再在这个地方工作了。
【问题讨论】:
-
您应该指定您正在使用的 SQL 数据库(以及当有多个可供选择时使用的存储引擎),因为运行时行为和优化能力取决于此。
-
谢谢你说得对,我加了(我在SQL 2008 R2下)
-
试试
OPTION (RECOMPILE)sommarskog.se/dyn-search-2008.html -
请注意,当您使用 '=' 时,通配符 ('%') 不能用作通配符
-
您可以通过使用 SET STATISTICS IO ON 运行每个查询来更深入地了解导致不同行为的原因,以查看哪些表被命中、多少次、多少页以及多少预读.
标签: sql-server performance tsql sql-server-2008-r2