问题:我们有一个非常复杂的搜索查询。如果其结果产生的行太少,我们通过使用相同查询的不太严格的版本UNIONing查询来扩展结果。
我们正在讨论一种不同的方法更快和/或更好的质量。我们将创建一个自定义sql函数,而不是UNIONing,它将返回匹配的分数。然后我们可以简单地按匹配分数排序。
关于性能:它会比UNION慢吗?
我们使用PostgreSQL。
任何建议都将不胜感激。
非常感谢你 最大
答案 0 :(得分:6)
如果您在实际环境中衡量两种方法的效果,则只能给出明确的答案。其他一切都充其量只是猜测。
这里有很多变量 - 表格的结构和数据的类型,数据的分布,你掌握的索引类型,服务器负载的重量 - 真的,几乎不可能预测任何结果。
所以真的 - 我最好的建议是:在实时系统上尝试两种方法,使用实时数据,而不仅仅是几十个测试行 - 并测量,测量和测量。
马克
答案 1 :(得分:2)
您想要通过自定义功能的“返回值”进行排序吗?然后数据库服务器无法使用索引。必须为表中的每个记录计算得分(尚未使用WHERE子句排除)并存储在某个临时存储/表中。然后在该临时表上执行order by。所以这很容易变得比你的联合查询慢(当然取决于你的联合语句)。
答案 2 :(得分:1)
添加我的一点......
+1到marc_s,完全同意他所说的 - 我只会说,你需要一个具有真实数据量的测试数据库服务器来测试,而不是生产服务器。
对于函数方法,将对每个记录执行该函数,然后按该结果排序 - 这不是索引列,因此我希望看到对性能的负面影响。然而,与其他方法的累积时间相比,这种影响有多大以及它实际上是否为负,只能通过测试来了解。
答案 3 :(得分:1)
在PostgreSQL 8.3
及以下,UNION
暗示DISTINCT
暗示排序,这意味着ORDER BY
,UNION
和DISTINCT
始终相同效率,因为两个人离开时使用了分拣。
在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没有排序。
SELECT DISTINCT
和UNION/INTERSECT/EXCEPT
不再总是生成排序输出(Tom)
因此,在新的PostgreSQL
版本中,我建议使用UNION
,因为它更灵活。
在旧版本中,性能将相同。