简体   繁体   English

使用嵌套查询与CTE和性能影响

[英]Using nested queries vs CTEs and performance impact

I've been using sql for a while, and would like to know whether and how it would make sense to convert a script containing a lot of CTE's into a regular nested script. 我一直在使用sql,并且想知道将包含大量CTE的脚本转换为常规嵌套脚本是否以及如何有意义。 I'm using: 我正在使用:

WITH cte_account_pricelevelid 
     AS (SELECT a.accountid, 
                a.pricelevelid 
         FROM   companypricelist a 
                JOIN(SELECT accountid 
                     FROM   crm_accountbase 
                     WHERE  defaultpricelevelid IS NULL) b 
                  ON a.accountid = b.accountid), 
     totals 
     AS (SELECT a.accountid, 
                a.pricelevelid 
         FROM   companypricelist a 
                JOIN(SELECT accountid 
                     FROM   crm_accountbase 
                     WHERE  defaultpricelevelid IS NULL) b 
                  ON a.accountid = b.accountid), 
     totalsgrouped 
     AS (SELECT pricelevelid, 
                Count(*) counts 
         FROM   totals 
         GROUP  BY pricelevelid), 
     final 
     AS (SELECT cte.accountid, 
                cte.pricelevelid, 
                frequency.counts 
         FROM   cte_account_pricelevelid cte 
                CROSS JOIN totalsgrouped frequency 
         WHERE  cte.pricelevelid = frequency.pricelevelid), 
     mycolumns 
     AS (SELECT b.accountid, 
                b.pricelevelid, 
                b.counts 
         FROM   (SELECT accountid 
                 FROM   crm_accountbase 
                 WHERE  defaultpricelevelid IS NULL) a 
                JOIN final b 
                  ON a.accountid = b.accountid), 
     e 
     AS (SELECT *, 
                Row_number() 
                  OVER ( 
                    partition BY accountid 
                    ORDER BY counts, pricelevelid ) AS Recency 
         FROM   mycolumns), 
     cte_result 
     AS (SELECT accountid, 
                pricelevelid 
         FROM   e 
         WHERE  recency = 1) 

SELECT a.accountid, 
       a.defaultpricelevelid, 
       b.pricelevelid 
FROM   crm_accountbase a 
       JOIN cte_result b 
         ON a.accountid = b.accountid 

I feel that it is silly to keep running the same query within my CTE's: 我觉得在我的CTE中继续运行相同的查询是愚蠢的:

SELECT accountid 
                     FROM   crm_accountbase 
                     WHERE  defaultpricelevelid IS NULL

But I don't know how to get around it. 但我不知道如何绕过它。 I suppose that I can convert this into, but don't know if there would be any performance gain. 我想我可以把它转换成,但不知道是否会有任何性能提升。

select * from (select * from(select * from(...

Is there an opportunity to tremendously improve performance by converting this into a nested SQL or just simplifying the CTE? 是否有机会通过将其转换为嵌套SQL或仅简化CTE来极大地提高性能? If so, would you kindly get me started? 如果是这样,你能帮我开始吗?

If accountid is indexed this join will not use that index 如果对accountid建立索引,则此连接将不使用该索引
The derived table has not index 派生表没有索引

SELECT a.accountid, a.pricelevelid 
  FROM companypricelist a 
  JOIN (SELECT accountid 
          FROM crm_accountbase 
                     WHERE  defaultpricelevelid IS NULL) b 
    ON a.accountid = b.accountid

This will use an index on accountid 这将使用accountid索引
Even if there is not an index on accountid it will be faster 即使没有关于accountid的索引,它也会更快

SELECT a.accountid, a.pricelevelid 
  FROM companypricelist a 
  JOIN crm_accountbase  b 
    ON a.accountid = b.accountid 
   AND b.defaultpricelevelid IS NULL

I tried to simplify it a bit. 我试着简化一下。 Mind running it and letting me know the results? 介意运行它,让我知道结果?

WITH 
 totals 
 AS (SELECT a.accountid, 
            a.pricelevelid 
     FROM   companypricelist a 
            JOIN(SELECT accountid 
                 FROM   crm_accountbase 
                 WHERE  defaultpricelevelid IS NULL) b 
              ON a.accountid = b.accountid), 
 totalsgrouped 
 AS (SELECT pricelevelid, 
            Count(*) counts 
     FROM   totals 
     GROUP  BY pricelevelid), 
 final 
 AS (SELECT cte.accountid, 
            cte.pricelevelid, 
            frequency.counts 
     FROM   totals cte 
            CROSS JOIN totalsgrouped frequency 
     WHERE  cte.pricelevelid = frequency.pricelevelid), 
 mycolumns 
 AS (SELECT b.accountid, 
            b.pricelevelid, 
            b.counts 
     FROM   final b 
          JOIN totals a
              ON a.accountid = b.accountid), 
 e 
 AS (SELECT *, 
            Row_number() 
              OVER ( 
                partition BY accountid 
                ORDER BY counts, pricelevelid ) AS Recency 
     FROM   mycolumns) 

SELECT a.accountid, 
       a.defaultpricelevelid, 
       b.pricelevelid 
FROM   crm_accountbase a 
       JOIN e b 
         ON a.accountid = b.accountid 
WHERE b.recency = 1

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

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