SQL Server“<>”与具有几百万行的表上的“=”相比,运算符非常慢

时间:2011-09-14 15:51:26

标签: sql sql-server performance

我有两张桌子。表单有~77000行。日志有大约270万行。

以下查询在不到一秒的时间内返回“30198”:

SELECT COUNT(DISTINCT logs.DOCID) FROM logs, forms WHERE logs.DOCID = forms.DOCID;

到目前为止,此查询已运行约15分钟,但仍未完成:

SELECT COUNT(DISTINCT logs.DOCID) FROM logs, forms WHERE logs.DOCID <> forms.DOCID;

为什么“不相等”的查询如此要慢得多?

3 个答案:

答案 0 :(得分:28)

因为=将连接操作减少到每个表中的一个匹配行(假设这些docid是唯一的)。

以这种方式思考 - 你和5个男孩和5个女孩一起跳舞:

Adam      Alice
Bob       Betty
Charly    Cathy
Dick      Deb
Evan      Elly

你用第一个字母将它们配对。所以

Adam->Alice
Bob->Betty
etc...

一次配对

但如果按“首字母不匹配”将它们配对,最终会得到:

Adam->Betty
Adam->Cathy
Adam->Deb
Adam->Elly
Bob->Alice
etc...
你已经大量增加了配对次数。这就是您的<>查询花费这么长时间的原因。您实际上是在尝试获取m x n行,而不仅仅是min(m,n)。使用这些数据,最终会得到25行,而不是5行。对于指定的表格大小,您使用的是77,000 * 2,700,000 = 207.9亿行,减去77,000,其中两个ID匹配,总共207,899,923,000行已连接的数据集。


根据您的查询要求,尝试左连接并查找空的右侧记录:

SELECT DISTINCT logs.DOCID
FROM logs
LEFT JOIN forms ON logs.DOCID = forms.DOCID
WHERE forms.DOCID IS NULL

答案 1 :(得分:2)

有两个原因:

  • 查询等价通常可以使用索引(如果可用),而查询非对等则不能

  • <>会返回更多数据。

您对<>的查询是假的。它应该返回什么?

答案 2 :(得分:1)

这完全取决于表中值的分布。例如,如果要搜索的列对99.99%的行具有相同的值(= forms.DOCID),而只有一行具有不同的值,则会看到完全相反的行为。