我试图做一些基本的维恩图减法,将临时表与一些实时数据进行比较,看看它们是如何不同的。
这个查询在1500万个返回的行中爆炸了很多,我注意到它复制了(10,000x或更多)一个已知的唯一字段 - 表明我的查询出现了一些问题(我的意思是这个行是被复制,我可以通过这个全球唯一标识符字段验证这一点。我原本期望最多返回200行:
select a.*
from TableOfLiveData a
inner join #TempDataToBeSubtracted b
on a.GUID <> b.guidTemp --I suspect the issue is here
where {here was a limiting condition that should have reduced my live
data to a "pre-join" count(*) of 20,000 at most...}
点击Execute之后,查询的运行时间比预期的要长得多,我可以看到在我必须取消之前已经返回了数百万行。
让我知道明显的是什么!?!?
编辑:仅供参考:如果没有包含where子句,我希望返回大量的行...
答案 0 :(得分:1)
感谢@Lamak和@MartinSmith提出的解决此问题的意见。
使用&#39; not equals&#39;在我的&#34; on&#34;我确保我会选择LiveTable中我的#TempTable中没有GUID的每一行,而不是按照我的意图选择一次,但是对于我的#TempTable中的每个条目,我的结果乘以大约20,000这种情况(#TempTable的基数)。
为了解决这个问题,我在#TempTable上使用&#34; Not In&#34;做了一个简单的子查询。声明中建议的声明。这个查询在一分钟内完成,并返回100行,这更符合我的期望:
select a.*
from TableOfLiveData a
where a.GUID not in (select b.guidTemp from #TempDataToBeSubtracted b)
and {subsequent constraint statement not relevant to question}
答案 1 :(得分:1)
虽然您的查询逻辑正确,但问题是您的联接中有“笛卡尔积”(nxm行),但之后执行where子句加入了,所以你有一个庞大的行数,必须执行where
子句...所以它会非常非常慢。
更好的方法是在键列上执行外部连接,但通过过滤错过的连接来放弃所有成功的连接:
select a.*
from TableOfLiveData a
left join #TempDataToBeSubtracted b on b.guidTemp = a.GUID
where a.field1 = 3
and a.field2 = 1515
and b.guidTemp is null -- only returns rows that *don't* match
这是有效的,因为当错过外部联接时,您仍然可以从主表中获取行,并且联接表中的所有列都是null
。
在(field1, field2)
上创建索引可以提高效果。