TSQL子查询过滤器性能问题

时间:2019-07-08 17:42:03

标签: sql-server tsql subquery

我正在处理此查询。当我从子查询到主查询分配日期过滤器时,响应时间从1秒增加到4.5分钟。

我不知道如何解决此问题并解决我的查询。我正在写查询和尝试过的方法。

谢谢您的帮助。

我的查询:

select
    START_DATE as DATE,
    [MINUTE] as MIN,
    map1.LT,
    ISNULL((SELECT
                (SELECT CAST((main.MIN) AS FLOAT)) /
                    (
            (nullif(
                (select cast(
                    (select 
                        sum(MIN2) 
                    from fooTable2 d2 
                        CROSS APPLY (select Top(1) LT from FooMap2 where x = d2.x) k2
                    where k2.LT = map1.LT
                        **-- PROBLEM CODE START**
                        and YEAR(d2.DATE) = YEAR(main.DATE) and MONTH(d2.DATE) = MONTH(main.DATE)
                        **-- PROBLEM CODE END**
                    ) as float)),0))
    as XX,
    ....... 

    ......
from Table1 main
OUTER APPLY (select Top(1) LT from FooMap where x = main.x) map1

我尝试创建虚拟表。

但不起作用。

declare @child table ([Year] smallint, [Month] smallint, [Total] float,[LTCode] nvarchar(20))

insert into @child ([LTCode],[Year],[Month],[Total])
(select 
    k2.LT,YEAR(d2.DATE) as YIL,MONTH(d2.DATE) as AY,sum(MIN) as SURE
from DURUS d2 
    CROSS APPLY (select Top(1) LT from FooMap2 where x = d2.x) k2
group by k2.LT,YEAR(d2.DATE),MONTH(d2.DATE))
... 
    ....
(select [Total] from @child where [YEAR] = YEAR(main.DATE) and [MONTH] = MONTH(main.DATE) and [LTCode] = map1.LT)

我该怎么办?

2 个答案:

答案 0 :(得分:1)

根本问题是数据模型。您需要过滤月份和年份,但将数据存储为DATE,DATETIME或类似数据。 没有简单的方法可以快速实现这一目标

super

WHERE FUNCTION(Input)= FUNCTION(Input)强制对每个表进行扫描,具有两个这样的过滤器意味着您要为每个表中的每一行两次触摸/评估每个值(d2.date和main.date)。要解决此问题,您最好的选择包括:

  1. 在每个表上按年份和月份添加一个持久化的计算列,然后添加适当的索引(按年,月,将查询中涉及的所有列添加为包含列。

  2. 使用索引视图来预先连接Durus和main,这并不简单,但是可行。

  3. 了解如何创建和利用索引正确的日历表。这将需要一些努力,但也会改变您的职业。

  4. 在联接的左侧使用其他过滤器...
    例如:在and YEAR(d2.DATE) = YEAR(main.DATE) and MONTH(d2.DATE) = MONTH(main.DATE) 之后添加WHERE子句,以过滤掉联接之前的所有其他行。

答案 1 :(得分:-1)

优化的常用方法: 1)从过滤器左侧删除计算 2)在单独的临时表或中间CTE查询中呈现子查询 3)不要使用表变量 4)在早期阶段,尝试在连接之前过滤尽可能多的数据