SQL Server 如何优化CTE查询

myzjeezk  于 2023-01-20  发布在  其他
关注(0)|答案(1)|浏览(153)

我有以下疑问(为了方便讨论,简化如下):

WITH CTE
   (
         Columns,
         DeliverDate,
         LastReplayDate
   )
   AS
   (
         SELECT IIF(LastReplayDate IS NULL, IIF(LastReplayDate>= DeliverDate, LastReplayDate,DeliverDate),LastReplayDate) AS SortDateColumn,R.* FROM
                (

                       SELECT 
                       Columns,
                       DeliverDate,
                       LastReplayDate
                       FROM MY_TABLE

                       WHERE
                              CONDITIONS
                              AND ( FIRST_HEAVY_FUNCTION)
                              AND ( SECOND_HEAVY_FUNCTION)
                ) R

                ORDER BY SortDateColumn DESC
                       OFFSET (@CurrentPageIndex - 1) * @PageSize ROWS
                FETCH NEXT 10 ROWS ONLY
   )
   SELECT CTE. *
   FROM CTE
   OPTION (RECOMPILE);

正如你所看到的,我使用CTE查询从其他查询排序数据。最后一个包括分页每10行。
对我来说最大的问题是:

WHERE
                          CONDITIONS
                          AND ( FIRST_HEAVY_FUNCTION)
                          AND ( SECOND_HEAVY_FUNCTION)

由于这些条件,返回时间有时会达到4分钟左右。没有它是相当快的(8-20秒)。当然,索引和改善查询从15分钟。但这仍然是缓慢的。
我想知道是否有可能将有问题的条件移到CTE之外,同时仍然从分页中获得所有10行?如果行数〈10,则执行另一个循环来收集丢失的行,以获得准确的10行作为最终结果。是否有可能?或者如何优化这样的查询?

bvpmtnay

bvpmtnay1#

几个问题:
1.你能把函数重写成内联表值函数吗?这样可以减轻压力

  1. CONDITIONS是否已经删除了足够多的行?因此HEAVY_FUNCTIONS只是顶部的樱桃。在这种情况下,您可能可以假装下推(但我不能保证它总是有效):
select *
from (
    select *
    FROM MY_TABLE
    WHERE
   CONDITIONS
    ) x
cross apply (
    select 1 AS test
    where dbo.FN_SLOW_FUNCTION(x.param1, x.param2) = 1
    ) filter1
cross apply (
    select 1 AS test
    where dbo.FN_ANOTHER_SLOW_FUNCTION(x.param3, x.param4) = 1
    ) filter2
ORDER BY SomeDate OFFSET ...

有一个名为FORCEORDER的OPTION提示可以保证SQL不会被过多地重新排列
1.你的指数好吗?

相关问题