sql - 使用嵌套查询与 CTE 以及性能影响

标签 sql sql-server sql-server-2008 tsql

我使用 SQL 一段时间了,想知道将包含大量 CTE 的脚本转换为常规嵌套脚本是否有意义以及如何有意义。我正在使用:

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 

我觉得在我的 CTE 中继续运行相同的查询是愚蠢的:

SELECT accountid 
                     FROM   crm_accountbase 
                     WHERE  defaultpricelevelid IS NULL

但我不知道如何解决这个问题。我想我可以将其转换为,但不知道是否会有任何性能提升。

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

是否有机会通过将其转换为嵌套 SQL 或只是简化 CTE 来极大地提高性能?如果是这样,您能让我开始吗?

最佳答案

如果 accountid 已编入索引,则此连接将不会使用该索引
派生表没有索引

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

这将使用 accountid 上的索引
即使accountid上没有索引也会更快

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

关于sql - 使用嵌套查询与 CTE 以及性能影响,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23764674/

相关文章:

sql-server - 将不同元素放入 SQL Server 中 xml 的一列中

SQL:如何从递归查询创建 View ?

c# - ExecuteNonQuery 要求命令有事务

SQL 查询删除与两个不同数据库的 3 个表内部连接中的重复值

sql - 为一个源行创建多行 View

sql - oracle sql date不迟于今天

sql - 使用第一个表中的键将许多表连接在一起进行所有连接?

c# - 是否可以在 UpdateCommand 运行之前以编程方式在 TextBox 控件中输入值

mysql - 在 SQL 中对字符串使用 'IN' 子句

mysql - 三列合并为一个日期