我有一个包含| id | postNumber |
列的表格。一个或多个条目属于一个postNumber
。我需要为每个postNumber
请求最新的条目。
SELECT `dienstbuch`.`id` , `dienstbuch`.`postNumber`
FROM `dienstbuch`
WHERE `dienstbuch`.`id`
IN (
SELECT max( `dienstbuch`.`id` )
FROM dienstbuch
GROUP BY `dienstbuch`.`postNumber`
)
ORDER BY `id` DESC
LIMIT 2000,10
在具有许多条目的表上使用时,查询需要很长时间。
我该如何改进?
答案 0 :(得分:3)
听起来好像你可以在一个直接查询中请求最大ID
SELECT max( `dienstbuch`.`id` ) maxId, postNumber
FROM dienstbuch
GROUP BY `dienstbuch`.`postNumber`
但是如果要检索多个字段,则需要子查询
SELECT `dienstbuch`.`id` , `dienstbuch`.`postNumber`, dienstbuch.field1, dienstbuch.field2
FROM `dienstbuch`
JOIN
(SELECT max( `dienstbuch`.`id` ) id, postNumber
FROM dienstbuch
GROUP BY `dienstbuch`.`postNumber`
) maxID
on dienstbuch.id=maxID.id and dienstbuch.postNumber=maxID.postNumber
ORDER BY dienstbuch.`id` DESC
LIMIT 2000,10
答案 1 :(得分:2)
为了获得更好的性能,作为IN (subquery)
谓词的替代,您可以使用JOIN到内联视图(也就是派生表)。
例如:
SELECT d.id
, d.postNumber
FROM dienstbuch d
JOIN ( SELECT MAX(e.id) AS max_id
FROM dienstbuch e
GROUP BY e.postNumber
) f
ON f.max_id = d.id
ORDER
BY d.id DESC
LIMIT 2000,10
这应该会更好,因为它正在执行内联视图的查询一次,而不是为每一行执行子查询,这就是MySQL如何评估IN (subquery)
谓词。
如果我们还需要结果集中表中的其他列,那么这是我们使用的正常模式。对于您的特定查询,您实际上根本不需要子查询。您可以使用此查询获得等效的结果集:
SELECT d.id
, d.postNumber
FROM dienstbuch d
GROUP
BY d.postNumber
ORDER
BY d.id DESC
LIMIT 2000,10
这很可能表现得更好,因为它避免了实现内联视图和执行JOIN操作的开销。
对于这两个查询,索引... ON dienstbuch (postNumber,id)
最有可能提高查询性能。