如何重新设计数据库以更有效地查找不同的值?

时间:2015-03-26 10:23:00

标签: sql sql-server

我经常需要从一个大表中选择性较低的列中选择一组distincs值,同时将其连接到其他表中,我无法将结果集中的条目过滤到合理的数量。

例如,我有一个包含20M行的表,其中someID有200个唯一值。我将此表与另一列上的其他结果集连接起来,并将20M行过滤到10M行(仍然很多),然后需要找到不同的someID。因此,无论如何,我最终都会进行10M行扫描,这很痛苦。

在这个连接中,没有办法更多地过滤结果,10M记录实际上是我需要找到distint someID的集合。

是否有任何标准方法可以重新设计表格或创建一些额外的表格来使这项工作更好?

2 个答案:

答案 0 :(得分:2)

您的基本查询是:

select distinct t1.someID
from table1 t1 join
     table2 t2
     on t1.col1 = t2.col1;

此查询的最佳索引为table1(col1, someId)table2(col1)

以下是该查询的另一个版本:

select distinct t1.someId
from table1 t1
where exists (select 1 from table2 t2 where t1.col1 = t2.col1);

在这种情况下,最佳索引为table1(someid, col1)。在这种情况下,SQL Server可能是智能的,并且在遇到匹配时停止查找exists值(虽然我有点怀疑)。您必须调查对数据生成的执行计划。

另一个想法进一步扩展了这一点:

select s.someId
from someIdtable s
where exists (select 1
              from table1 t1 join
                   table2 t2
                   on t1.col1 = t2.col1 and t1.someId = s.someId);

这将删除外部distinct,仅取决于exists子句中的半连接。最佳指数为table1(someid, col1)

在某些情况下,此版本可能具有最佳性能 - 例如,如果所有someIds都在结果集中。另一方面,如果很少,那么性能可能会很差。

答案 1 :(得分:0)

我偷了"基本查询"来自戈登的回答:

select t1.someID
from table1 t1
join table2 t2 on t1.col1 = t2.col1
group by t1.someID

此查询符合索引视图的要求。您可以索引此查询。运行它将导致一个简单的聚簇索引扫描,它的价格便宜。