SQL性能:UNION或ORDER BY

时间:2009-07-28 16:12:54

标签: sql performance postgresql

问题:我们有一个非常复杂的搜索查询。如果其结果产生的行太少,我们通过使用相同查询的不太严格的版本UNIONing查询来扩展结果。

我们正在讨论一种不同的方法更快和/或更好的质量。我们将创建一个自定义sql函数,而不是UNIONing,它将返回匹配的分数。然后我们可以简单地按匹配分数排序。

关于性能:它会比UNION慢吗?

我们使用PostgreSQL。

任何建议都将不胜感激。

非常感谢你 最大

4 个答案:

答案 0 :(得分:6)

如果您在实际环境中衡量两种方法的效果,则只能给出明确的答案。其他一切都充其量只是猜测。

这里有很多变量 - 表格的结构和数据的类型,数据的分布,你掌握的索引类型,服务器负载的重量 - 真的,几乎不可能预测任何结果。

所以真的 - 我最好的建议是:在实时系统上尝试两种方法,使用实时数据,而不仅仅是几十个测试行 - 并测量,测量和测量。

马克

答案 1 :(得分:2)

您想要通过自定义功能的“返回值”进行排序吗?然后数据库服务器无法使用索引。必须为表中的每个记录计算得分(尚未使用WHERE子句排除)并存储在某个临时存储/表中。然后在该临时表上执行order by。所以这很容易变得比你的联合查询慢(当然取决于你的联合语句)。

答案 2 :(得分:1)

添加我的一点......

+1到marc_s,完全同意他所说的 - 我只会说,你需要一个具有真实数据量的测试数据库服务器来测试,而不是生产服务器。

对于函数方法,将对每个记录执行该函数,然后按该结果排序 - 这不是索引列,因此我希望看到对性能的负面影响。然而,与其他方法的累积时间相比,这种影响有多大以及它实际上是否为负,只能通过测试来了解。

答案 3 :(得分:1)

PostgreSQL 8.3及以下,UNION暗示DISTINCT暗示排序,这意味着ORDER BYUNIONDISTINCT始终相同效率,因为两个人离开时使用了分拣。

PostgreSQL 8.3上,此查询返回已排序的结果:

SELECT  *
FROM    generate_series(1, 10) s
UNION
SELECT  *
FROM    generate_series(5, 15) s

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

PostgreSQL 8.4开始,HashAggregate成为UNION可能会更快(几乎总是),但不保证有序输出。

同一查询在PostgreSQL 8.4上返回以下内容:

SELECT  *
FROM    generate_series(1, 10) s
UNION
SELECT  *
FROM    generate_series(5, 15) s

10
15
8
6
7
11
12
2
13
5
4
1
3
14
9

,正如您所看到的那样,resuts没有排序。

PostgreSQL change list提及:

  

SELECT DISTINCTUNION/INTERSECT/EXCEPT不再总是生成排序输出(Tom)

因此,在新的PostgreSQL版本中,我建议使用UNION,因为它更灵活。

在旧版本中,性能将相同。