我在SELECT查询中添加了一条CASE...WHEN语句,这会导致查询多运行25秒
有什么想法是为什么吗?
以下是原始查询,耗时约7-8秒(即没有CASE语句)
注意:我通过添加一些硬编码的值简化了查询,这样代码的焦点就会集中在上面列出的问题点上
select * from (
select
(row_number() over (
order by b.BookTitle
))
as RowNumber,
b.*
from
Books b
) as t1
where
RowNumber between 40 and 60
order by
RowNumber下面是CASE语句(注意: case语句用于确定如何对结果进行排序)
declare @SortByField nvarchar(255)
select @SortByField = NULL
select * from (
select
case @SortByField
when 'Published' then
(row_number() over (
order by b.PublishDate, b.BookTitle
))
when 'Price' then
(row_number() over (
order by b.RetailPrice, b.BookTitle
))
when 'Author' then
(row_number() over (
order by b.AuthorName desc, b.BookTitle
))
when 'Sold' then
(row_number() over (
order by b.ItemsSold desc, b.BookTitle
))
else
-- Notice in the first line of code for this snippet that @SortByField is
-- set to NULL? So this condition should evaluate yet it still takes significantly longer
(row_number() over (
order by b.BookTitle
))
end as RowNumber,
b.*
from
Books b
) as t1
where
RowNumber between 40 and 60
order by
RowNumber发布于 2014-11-29 09:07:16
嗯,它必须运行所有的row_numbers(),这显然需要一些时间。请尝试改用以下子查询:
from (select row_number() over (order by (case when @SortByField = 'Published' then PublishDate end),
(case when @SortByField = 'Price' then Price end),
(case when @SortByField = 'Author' then Author end),
(case when @SortByField = 'Sold' then Sold end),
BookTitle
) as RowNumber,
b.*
from Books b
) b这看起来可能是相同的逻辑,但是它只调用row_number()一次--而且row_number()通常比case更昂贵,所以只调用它一次应该是一种改进。
发布于 2014-11-29 09:45:55
第一个查询可能使用BookTitle列上的索引,因此数据已经是有序的。但是第二个查询是什么呢?
我认为它首先必须评估所有行的case块,然后进行排序。你检查执行计划了吗?
我将尝试基于给定的参数@SortByField在过程中动态构建sql语句,然后使用sp_executesql执行它。因此,每个输入参数都有自己的执行计划,而不是整个过程只有一个。并且每次执行都使用正确的索引。
https://stackoverflow.com/questions/27197809
复制相似问题