SQL中如何避免叉积/笛卡尔/全连接?

问题描述 投票:0回答:1

我们有一个表格 A,其中包含“ETA To Destination”(预计到达目的地)分钟数。

id 预计到达目的地(分钟) 分数
1 45
2 75

有一个配置表,我们根据时间间隔定义了分数。

例如 - 如果 预计到达时间在 31 到 60 分钟之间,得分为 5 分, ETA在61到120分钟之间,得分为10分,

从时间开始 到时间 分数
0 30 2
31 60 5
61 120 10

我们需要根据配置表中的ETA分钟数(from和to time之间)找到分数(在表A中)

我不想编写将在表中进行顺序扫描的完整连接。有没有更好的选择或更好的设计。

A可以有百万条记录,配置表可以有更多的时间间隔行。

database postgresql join cartesian-product
1个回答
0
投票
SELECT a.id, a.eta, s.score
FROM   a
JOIN   score_tbl s ON a.eta BETWEEN s.from_time AND s.to_time
ORDER  BY a.eta DESC NULLS LAST  -- how to break ties??
LIMIT  50;

有了a(eta)上的

匹配索引
来支持这个查询,这只是毫秒的问题。您在评论中提到的
LIMIT 50
使一切变得不同。理想情况下:

CREATE INDEX a_eta_id_idx on a (eta DESC NULLS LAST) INCLUDE (id);

我们可以保持这么简单,因为更高的

eta
与更高的
score
相关。

详情以未公开信息为准。基本上,any B 树索引以

eta
作为前导列或唯一列就可以了。但是你必须匹配尚未公开的规格如何打破关系。

DESC NULLS LAST
仅当
eta
可以是
null
(未定义
NOT NULL
)。否则只是
DESC
。参见:

如果

eta
上可以有重复项,您将必须定义如何打破平局。我的查询进行了任意选择。但这对于正确的分页来说还不够好。参见:

© www.soinside.com 2019 - 2024. All rights reserved.