T-SQL独特计数查询...可以用EXISTS或其他东西进行优化吗?

时间:2013-05-03 15:07:41

标签: sql sql-server tsql

有没有办法让这个查询运行得更快(意味着从SQL Server中获取更少的读取/ IO)。逻辑基本上是

  1. 我从列中计算不同的值
  2. 如果有超过1个不同的值,则视为现有
  3. 列表使用列的名称构建,如果存在则为1或0
  4. 我想用EXISTS做一些事情(在t-sql中,如果SQL Server找到与EXISTS谓词的匹配,则终止对表/索引的扫描)。我不确定这个查询是否可行。

    注意:我不是在寻找像桌子上有索引的答案......远远超出:)

        with SomeCTE as
                (                   
        select 
        count(distinct(ColumnA)) as ColumnA,        
        count(distinct(ColumnB)) as ColumnB,        
        count(distinct(ColumnC)) as ColumnC
    from VERYLARGETABLE
            )
    select 'NameOfColumnA', case when ColumnA > 1 then 1 else 0 end from SomeCTE
    UNION ALL
    select 'NameOfColumnB', case when ColumnB > 1 then 1 else 0 end from SomeCTE
    UNION ALL
    select 'NameOfColumnC', case when ColumnC > 1 then 1 else 0 end from SomeCTE
    

    只是复制我在评论中发布的内容。 所以在测试了这个解决方案它使查询运行“更快”。举两个例子。一个查询从50秒到3秒。另一个从9分钟以上(停止运行)下降到1分03秒。此外,我缺少索引(因此根据DTA应该运行速度快14%)我也在SQL Azure数据库中运行它(在I / O,CPU和tempddb内存方面你受到严重限制)...非常好解决方案四周。一个缺点是min / max对位列不起作用,但可以转换它们。

1 个答案:

答案 0 :(得分:8)

如果列的数据类型允许聚合函数,并且如果有索引,则每列都有一个索引,这将很快:

SELECT 'NameOfColumnA' AS ColumnName,
       CASE WHEN MIN(ColumnA) < MAX(ColumnA)
                THEN 1 ELSE 0
       END AS result
FROM VERYLARGETABLE 

UNION ALL 

SELECT 'NameOfColumnB',
       CASE WHEN MIN(ColumnB) < MAX(ColumnB)
                THEN 1 ELSE 0
       END 
FROM VERYLARGETABLE 

UNION ALL 

SELECT 'NameOfColumnC' 
       CASE WHEN MIN(ColumnC) < MAX(ColumnC)
                THEN 1 ELSE 0
       END 
FROM VERYLARGETABLE ;