我有两张桌子。表单有~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;
为什么“不相等”的查询如此要慢得多?
答案 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)
,而只有一行具有不同的值,则会看到完全相反的行为。