我有这样的内部联接:
INNER JOIN Area AS area ON (Area.Id = psaLocalityOrCity.AreaId OR Area.Id = psaDbl.AreaId)
psaLocalityOrCity是我需要区域的位置,但是有些记录在psaLocalityOrCity中重复。这些,仅有这些,已作为单个记录提取到psaDbl中。上面的INNER JOIN假设我找到了两个组中所有地方的所有区域,但是这个OR语句导致它运行了很长时间。这是什么原因?是否有任何修复可以优化查询再次运行6秒而不是3分钟?
答案 0 :(得分:2)
INNER JOIN
的 OR
将导致嵌套循环连接,这是最慢的一种。一种方法是使用UNION ALL
,如评论中所建议的那样。另一个是使用两个LEFT JOIN
。结构的一个例子:
SELECT . . .,
COALESCE(aloc.col1, adbl.col1)
FROM psaLocalityOrCity loc LEFT JOIN
Area aloc
ON aloc.Id = loc.AreaId LEFT JOIN
Area adbl
ON adbl.Id = psaDbl.AreaId
WHERE aloc.id is not null or adbl.id is not null
注意:如果Area
中的多行与每列匹配,则无法使用此功能。但是,由于匹配位于名为id
的列上,因此似乎不太可能。
答案 1 :(得分:0)
或者在加入时往往很慢 查询优化器进入循环连接
JOIN Area AS area
ON Area.Id = psaLocalityOrCity.AreaId
OR Area.Id = psaDbl.AreaId
与现在不一样,你有两个AREA来处理
但是你知道该地区来自哪里
可能会导致更多行,但会更快
Linoff的答案更好
LEFT JOIN Area AS AreaCity
ON AreaCity.Id = psaLocalityOrCity.AreaId
LEFT JOIN Area AS AreaDpl
ON AreaDpl.Id = psaDbl.AreaId
答案 2 :(得分:-1)
有一些方法可以提高此类查询的效果。(但我不确定它是否适合您。)
可以采取以下措施来提高性能:
1.在所有表格中使用WITH(NOLOCK)
2.如果您每天多次使用查询,请尝试创建缓存表,即将结果填充到表中并使用select语句始终从表中检索结果。
3.在select语句中只放置必需的列。
答案 3 :(得分:-1)
很抱歉,通过将SELECT与UNION结合使用,将psaLocalityOrCity和psaDbl组合成一个来解决此问题。这允许我从INNER JOIN中消除OR,并且查询现在执行得更好。从这里得到了这个想法: Is having an 'OR' in an INNER JOIN condition a bad idea?
感谢您的所有建议