4

有什么方法可以让这个查询运行得更快(意味着从 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

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

4

1 回答 1

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 ;
于 2013-05-03T15:30:41.903 回答