【问题标题】:T-SQL distinct count query...can it be optimized with an EXISTS or something else?T-SQL 不同计数查询...可以用 EXISTS 或其他东西优化吗?
【发布时间】:2013-05-03 15:07:40
【问题描述】:

有什么方法可以让这个查询运行得更快(意味着从 SQL Server 中减少读取/IO)。逻辑本质上是

  1. 我从一列中计算不同的值
  2. 如果有超过 1 个不同的值,则将其视为存在
  3. 使用列名和 1 或 0(如果存在)构建列表

我想对 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

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

【问题讨论】:

  • if there is any more than 1 distinct value, it is considered as existing 您对计数不感兴趣,只是知道它是 0,1 或大于 1,对吧?列的数据类型是什么?
  • 列是字符串。是的,你是对的...0 或 1,我愿意做一个存在。
  • 我们是否假设各个列上没有索引?
  • @Martin 所有这些列都已编入索引/具有统计信息。它是只读的,所以我在索引方面做得太过火了……这只是运行的许多查询中的一个,因此可能还有与该查询不相关的索引(或可能混淆优化器)。

标签: sql sql-server tsql


【解决方案1】:

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

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 ;

【讨论】:

  • 使用 MIN/MAX 比较的好主意
  • 现在要测试这个......这看起来很有希望。
  • 所以在测试了这个解决方案之后。它使查询运行“更快”。举两个例子..一个查询从 50 秒到 3 秒。另一个从 9+ 分钟(停止运行)下降到 1min03 秒。此外,我缺少索引(因此根据 DTA 应该运行速度快 14%)我也在 SQL Azure DB 中运行它(在 I/O、CPU 和 tempddb 内存方面你被严重限制)......非常好解决方案。一个缺点是 min/max 不适用于位列,但可以转换。
  • @BartCzernicki - 转换意味着不会使用索引。对于那些SELECT TOP 1 Flag FROM Table ORDER BY Flag ASC|DESC 会更好。
猜你喜欢
  • 2012-03-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-04
  • 1970-01-01
  • 2011-04-25
相关资源
最近更新 更多