我如何改进以下查询,因为我认为我遗漏了一些东西而且可以做得更好:( 我有A表和A到B的一对多 我想要一些来自A的信息和来自B的一行链接到具有最高序号的A。 我想出了这个:
SELECT A.*,
(
SELECT B.value
FROM B
WHERE A.idB = B.id
ORDER BY B.seqNr DESC LIMIT 1
)
FROM A
性能对我来说很重要,这是我最好的选择吗?
答案 0 :(得分:1)
这可能是你最好的选择,特别是如果你只访问A和B中的少量行。
如果您打算覆盖所有行,您可以尝试使用窗口聚合解决问题,将行号分配给B中的行:
SELECT * FROM (
SELECT A.*, B.*, ROW_NUMBER() OVER(PARTITION BY B.id ORDER BY B.seqNr DESC) AS seqidx
FROM A JOIN B ON A.idB = B.id
) WHERE seqidx = 1
这将使用大量的临时空间...考虑只是将A和B主键从聚合中取出并稍后再加入它们(从您的查询中不清楚您的pkey列是什么,因为B. id显然不是)
答案 1 :(得分:0)
虽然更大,但这可能会更好。
SELECT
A.*,
B3.value
FROM
(
SELECT B.id, MAX(B.seqNr) MaxSeqNr
FROM B
GROUP BY B.id
) B2
INNER JOIN
B B3
ON
B2.id = B3.id AND B2.MaxSeqNr = B3.seqNr
INNER JOIN
A
ON
A.id = B3.id
也可能会表现更差。需要一些真实的数据来测试和查看。 : - )
同时在B.id, B.seqNr DESC
上创建复合索引可以提高原始和此备用查询的效果。
如果您可以阻止组织中的任何理论纯粹主义者,则可以通过添加LatestPaymentForA
字段并使用触发器使此字段保持同步来显着提高性能。每当将新记录插入B
时,更新现有记录B
,其中LastPaymentFromA
为真且具有相同id
,然后将LastPaymentFromA
的新记录插入真。
然后你可以像这样快速地做点什么:
SELECT
A.*,
B.value
FROM
A
INNER JOIN
B
On
A.id = B.id
WHERE
B.LastPaymentFromA = 1