SQL WITH子句执行顺序

时间:2013-06-24 13:52:36

标签: sql-server tsql

我在存储过程中进行过滤,排序和分页操作。这些操作的顺序应该是 search-> order-> paging 的执行顺序。我不知道我的存储过程是先按语句排序还是先搜索操作。所以我的问题是:

1)此存储过程的执行顺序是什么?

2)如果order by语句在搜索语句之前执行,我该如何首先执行搜索操作?

CREATE PROCEDURE [dbo].[Grid_Feedbacks_Select_All]
@search nvarchar(100),
@orderby nvarchar(50),
@orderbydirection nvarchar(4),
@skipLength int,
@length int
AS
BEGIN

--THIS PART IS ORDER BY PART
WITH CTE_Results
AS (
SELECT ROW_NUMBER() OVER (ORDER BY
    CASE WHEN (@orderby = 'Subject' AND @orderbydirection='asc')
                THEN Subject
    END ASC,
    CASE WHEN (@orderby = 'Subject' AND @orderbydirection='desc')
               THEN Subject
    END DESC,

    CASE WHEN (@orderby = 'Text' AND @orderbydirection='asc')
              THEN Text
    END ASC,
    CASE WHEN @orderby = 'Text' AND @orderbydirection='desc'
             THEN Text
    END DESC
) AS ROWNUM,

Count(*) over () AS TotalCount, 
(
    --THIS PART IS SEARCH PART
    SELECT COUNT(*) FROM Feedbacks f(nolock)) AS TotalRecordsCount,
    f.Id, 
    f.Response, 
    f.Subject, 
    f.Text, 
    u.Username, 
    c.FirmName, 
    c.Name, 
    c.Surname

    FROM Feedbacks f(nolock), Users u, Customers c 
    WHERE
    f.UserId = u.Id 
    AND u.CustomerId = c.Id
    OR(f.Text LIKE '%' + @search + '%')
    OR (u.Username LIKE '%' + @search + '%')
    OR (c.Name LIKE '%' + @search + '%')
)
--THIS PART IS PAGING PART
SELECT * FROM CTE_Results AS CPC
WHERE CPC.ROWNUM > @skipLength AND 
CPC.ROWNUM < @skipLength + @length + 1
ORDER BY CPC.ROWNUM ASC

END

1 个答案:

答案 0 :(得分:0)

答案是“不知道,不关心”。 SQL语句是描述性的。他们描述了正在产生的输出。 SQL 不是一种过程语言,因此SQL引擎可以自由选择它喜欢的任何执行顺序和优化方法。

执行顺序对结果没有任何影响。查询计划用于返回所有结果,而不仅仅是特定的子集。

换句话说,你担心错误的事情。只需确保查询返回您想要的数据并以最佳方式编写,以便优化器利用其功能。

编辑:

要明确的是,SQL Server documentation明确指出:

  

当SQL Server处理连接时,查询引擎选择最多   处理的有效方法(有几种可能性)   加入。各种连接的物理执行可以使用许多不同的   优化,因此无法可靠预测。

如果查询中有大量连接(超过OP),优化程序可能无法考虑所有可能性。在这种情况下,连接顺序可以影响查询计划。但更重要的是,优化程序用于选择连接操作的排序和类型的统计信息。 Microsoft已经投入了大量精力来选择最佳执行计划。

即便如此,在某些情况下,优化器可能是错误的。您可以通过对连接使用显式查询提示来影响结果。我不知道任何适用于OP问题的查询提示。并且,除非存在当前的性能问题,否则我认为它甚至不值得考虑。