我想知道关于stackoverflow 问题的答案中提供的解决方案的相对性能,我决定运行一些测试。
OP 希望在给定一组优先级递减的条件的情况下获得第一个匹配行。两种解决方案都涉及一个伪列,但一个(我的)涉及将多个SELECT
语句UNION ALL
组合在一起,而另一个则构建一个CASE
表达式。
我分享我的结果,希望有人会觉得这有用。
我想知道关于stackoverflow 问题的答案中提供的解决方案的相对性能,我决定运行一些测试。
OP 希望在给定一组优先级递减的条件的情况下获得第一个匹配行。两种解决方案都涉及一个伪列,但一个(我的)涉及将多个SELECT
语句UNION ALL
组合在一起,而另一个则构建一个CASE
表达式。
我分享我的结果,希望有人会觉得这有用。
您的测试设计有缺陷。您正在测试不正确的结果。
我在您所指的 SO 上添加了问题的答案。
在您的CASE 版本中,您不能添加
ORDER BY col1, col2
. 必须是ORDER BY precedence
。但它仍然是不正确的。您必须对ORDER BY
各个条件的分数求和才能首先获得满足最多条件的行。同样,您的UNION ALL 版本会产生不正确的结果。
然而,这些似乎都不是必需的,有一个更简单、更快速的解决方案,使用
UNION ALL
. 参考我对SO问题的回答或者使用sqlfiddle来玩对于仅包含几行的表,我看不出执行时间有任何差异(虽然查询计划不同,但结果未显示)。
然后我重新使用了之前实验中的测试表。该表包含 436421 行,结构如下:
现在测试运行如下(选择的条件返回不到所有行的 2% 没有
LIMIT
):案例版本
联合所有版本
(两者都运行了几次以排除缓存影响。)
在此设置中
UNION ALL
,速度更快,因为它命中的行少得多——这反映在顺序扫描和排序中。现在我创建了两个索引:
随后的运行给出了截然不同的结果:
带索引的 CASE 版本
带索引的 UNION ALL 版本
这是一个巨大的差异,这次
CASE
是赢家。执行计划再简单不过了……