繁体   English   中英

通过SQL Server改善SQL查询的性能

[英]Improve the performance of a SQL Query via SQL Server

我正在寻找提高“去年参加”查询的性能的方法。 现在,需要20多分钟才能运行此块。

LYA将最近参加某一特定活动的年份作为参加活动,并查找他们在最高活动之前参加的年份。 例如,如果他们参加了2018年的活动,则查询将查找2018年之前参加的最后一年。

2018年的LYA应该返回Null

数据应返回以下内容:

CompanyID   MarketID    Industry    LAST YEAR ATTENDED
-------------------------------------------------------
123456      1234        GIFT        2018
123457      1234        HOME        2017
123458      1234        GIFT        2018
123459      1234        HOME        2018
123460      1234        APPAREL     2018
123461      1234        HOME        2018
123462      1234        HOME        2017
123463      1234        APPAREL     2018

有人可以协助吗?

SELECT DISTINCT 
    COMPANYID, MARKETID, INDUSTRY,
    [LAST YEAR ATTENDED] = (SELECT MAX(YEAR(attdate))
                            FROM v_marketatt va
                            WHERE va.companyid = vm.companyid
                              AND YEAR(attdate) <> (SELECT MAX(YEAR(attdate))
                                                    FROM v_marketatt vb
                                                    WHERE vb.companyid = vm.companyid)
                              AND MARKETCODE LIKE 'SM1%')
FROM
    v_marketatt vm
WHERE 
    MARKETID IN (835, 1032, 1101)

更新:

发现版本比其他版本更有效。 在克隆上运行时间减少到7分钟。 不是让子查询两次浸入我的视图,而是让它浸入一次。

select
DISTINCT COMPANYID,
MARKETID,
INDUSTRY,
CSTATUS,
[LAST YEAR ATTENDED] = (select max(year(attdate)) from v_marketatt va where year(attdate) <> (select max(year(attdate)) from v_marketatt) AND MARKETCODE LIKE 'SM1%' AND va.COMPANYID = vm.COMPANYID)
from v_marketatt vm
WHERE MARKETID IN (835,1032,1101)
;

感谢所有回应。

[LAST YEAR ATTENDED]字段具有一个子查询,可计算每次迭代的最大年份。您可以尝试将此查询移至类似

    select DISTINCT COMPANYID, MARKETID, INDUSTRY,
    [LAST YEAR ATTENDED] 
    from v_marketatt vm
    inner join 
    ( select max(year(attdate)) as [LAST YEAR ATTENDED]
                    from v_marketatt ivm 
           where year(ivm.attdate) <> (select max(year(attdate))
                                            from v_marketatt vb
                                            where vb.companyid = 
                 ivm.companyid)
       AND MARKETCODE LIKE 'SM1%')va on va.companyid = vm.companyid
          --where companyid not in (select distinct companyid from 
      v_marketatt where marketid in (602))
       WHERE MARKETID IN (835,1032,1101)

我没有运行此查询,可能会对语法进行一些小的更正,但是如果您了解这个概念,则应该很容易选择和修复。

对语法表示歉意,我很快就将它们综合起来。 但是我怀疑使用CTE应该会大大提高性能。 我也不太确定您在这里做什么:

WHERE va.companyid = vm.companyid
                              AND YEAR(attdate) <> (SELECT MAX(YEAR(attdate))
                                                    FROM v_marketatt vb)
                              AND MARKETCODE LIKE 'SM1%'

所以我把那一块留了。 尝试这样的事情,应该会有所帮助,而我上面提到的部分可能需要澄清,这可能会使其他事情需要调整。

;with Year_CTE (year)

as

(SELECT MAX(YEAR(attdate), va.companyid)
                            FROM v_marketatt va
                            WHERE va.companyid = vm.companyid
                              AND YEAR(attdate) <> (SELECT MAX(YEAR(attdate))
                                                    FROM v_marketatt vb)
                              AND MARKETCODE LIKE 'SM1%')

SELECT DISTINCT 
    COMPANYID, MARKETID, INDUSTRY,
    vb.[YEAR]
FROM
    v_marketatt vm
join Year_CTE vb on vb.companyid = vm.companyid
WHERE 
    MARKETID IN (835, 1032, 1101)

如果您需要“此之前的那个”,我建议使用LEAD()LAG()函数。 尽管我不太确定我是否完全理解您的示例(请参阅Thorsten Kettners的评论),但通过解释,我认为您想要的是以下内容:

;WITH years
   AS (
        SELECT COMPANYID, MARKETID, INDUSTRY, YEAR_ATTENDED = Year(attdate)
          FROM v_marketatt
          WHERE MARKETID IN (835, 1032, 1101)
           AND MARKETCODE LIKE 'SM1%' -- not sure about this one, the example isn't very clear
         GROUP BY COMPANYID, MARKETID, INDUSTRY, Year(attdate)
       ),
     last_ones
  AS (
        SELECT row_nbr = ROW_NUMBER() OVER ( PARTITION BY  COMPANYID, MARKETID, INDUSTRY ORDER BY YEAR_ATTENDED DESC),
               COMPANYID, MARKETID, INDUSTRY, 
               LAST_YEAR_ATTENDED = YEAR_ATTENDED,
               PREV_YEAR_ATTENDED = LEAD(YEAR_ATTENDED, 1, NULL) OVER (PARTITION BY COMPANYID, MARKETID, INDUSTRY ORDER BY YEAR_ATTENDED DESC)
          FROM years
     )

SELECT COMPANYID, MARKETID, INDUSTRY, 
      LAST_YEAR_ATTENDED,
      PREV_YEAR_ATTENDED
 FROM last_ones
WHERE row_nbr = 1

由于我这里没有表格或数据,因此我没有测试查询,但是我希望它可以帮助您...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM