首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >CASE语句需要很长时间

CASE语句需要很长时间
EN

Stack Overflow用户
提问于 2014-11-29 09:02:41
回答 2查看 1.6K关注 0票数 1

我在SELECT查询中添加了一条CASE...WHEN语句,这会导致查询多运行25秒

有什么想法是为什么吗?

以下是原始查询,耗时约7-8秒(即没有CASE语句)

注意:我通过添加一些硬编码的值简化了查询,这样代码的焦点就会集中在上面列出的问题点上

代码语言:javascript
复制
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语句用于确定如何对结果进行排序)

代码语言:javascript
复制
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
EN

回答 2

Stack Overflow用户

发布于 2014-11-29 09:07:16

嗯,它必须运行所有的row_numbers(),这显然需要一些时间。请尝试改用以下子查询:

代码语言:javascript
复制
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更昂贵,所以只调用它一次应该是一种改进。

票数 2
EN

Stack Overflow用户

发布于 2014-11-29 09:45:55

第一个查询可能使用BookTitle列上的索引,因此数据已经是有序的。但是第二个查询是什么呢?

我认为它首先必须评估所有行的case块,然后进行排序。你检查执行计划了吗?

我将尝试基于给定的参数@SortByField在过程中动态构建sql语句,然后使用sp_executesql执行它。因此,每个输入参数都有自己的执行计划,而不是整个过程只有一个。并且每次执行都使用正确的索引。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27197809

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档