我有以下表格布局:四个不同的表格,每个表格包含大约1000万到1500万个条目。每个表的三个字符串属性是相同的(让我们称它们为Id,Name1,Name2)。现在我们要读取具有相同Id列但不同(Name1,Name2)元组的所有条目。据估计,所有条目中只有不到0.5%是匹配的。
我们创建了一个视图AllEntries(基本上是所有四个表中UNION ALL的相关属性),我们的查询如下所示:
SELECT *
FROM AllEntries
GROUP BY Id
HAVING COUNT(DISTINCT(Name1)) > 1 OR COUNT(DISTINCT(Name2)) > 1
在我们的测试数据库中执行查询,每个表中有200万个条目(即视图中的800万个条目)已经需要大约2到3分钟(不错的服务器)。
问:是否可以改善性能?
答案 0 :(得分:2)
尝试使用ROW_NUMBER()
代替传统GROUP BY/HAVING
方法的CTE:
;with cteDups as
(
Select *
,ROW_NUMBER() Over(Partition By Name1 Order By Id) rn1
,ROW_NUMBER() Over(Partition By Name2 Order By Id) rn2
From AllEntries
)
Select *
From cteDups
Where rn1 > 1
Or rn2 > 1
答案 1 :(得分:1)
count(distinct)
比其他聚合函数更耗费资源。你可以尝试:
SELECT *
FROM AllEntries
GROUP BY Id
HAVING min(Name1) <> max(Name1) or min(Name2) <> max(Name2);
如果您在每个子表中的id, Name1
和id, Name2
上构建索引,则以下内容应显示出显着的性能提升:
select ae.*
from AllEntries ae
where exists (select 1 from subtable1 ae2 where ae.id = ae2.id and ae.Name1 <> ae2.Name1) or
exists (select 1 from subtable2 ae2 where ae.id = ae2.id and ae.Name1 <> ae2.Name1) or
. . .
将它们拆分为子查询,以鼓励优化器在每个子查询上使用不同的索引。
答案 2 :(得分:0)
这在很大程度上取决于你的索引,但是对于这个大小的表来说,具有OR条件的最后一个语句肯定不是理想的。另外,我不确定为什么你需要一个SELECT *来...额外的IO。如果可以,请避免使用它。
尝试这样的事情......
SELECT id, COUNT(name1)
FROM {table}
GROUP BY id
HAVING COUNT(*) > 1
UNION ALL
SELECT id, COUNT(name2)
FROM {table}
GROUP BY id
HAVING COUNT(*) > 1
UNION ALL
等
这将允许您利用ID上的索引并避免使用COUNT DISTINCT,这是一项非常昂贵的功能。
如果您想获取这些特定记录,我建议您编写CTE并将上述查询的结果与数据本身相结合....返回所有ID和计数的名称(*)更高。
对于您希望以某种方式重复的记录很少,另一个选项就是
SELECT id, COUNT(*)
FROM {table}
GROUP BY id
HAVING COUNT(*) > 1
然后使用id将你的数据表连接起来....这样就可以避免使用union所有内容的额外工作,并向你展示每个记录哪些ID重复。对我而言,无论如何......你可能不想要重复的ID: - )
答案 3 :(得分:0)
UNION正在杀死它 在联合之后,name1或name2上没有使用索引 无法使用UNION
在视图上创建索引你会认为这已被打破,但试一试 它使用索引并支持少量匹配 如果你没有关于word1和word2的索引,那么就这样做
select distinct ta.ID
from t1 as ta
join t1 as tb
on ta.ID = tb.ID
and ( (ta.word1 <> tb.word1) or (ta.word2 <> tb.word2) )
union
select distinct ta.ID
from t1 as ta
join t2 as tb
on ta.ID = tb.ID
and ( (ta.word1 <> tb.word1) or (ta.word2 <> tb.word2) )
union
t1 t3
union
t1 t4
union
t2 t2
union
t2 t3
union
t2 t4
union
t3 t3
union
t3 t4
union
t4 t4