选择单个最大值

时间:2015-11-08 15:43:53

标签: mysql sql optimization query-optimization

假设我需要从几个表中提取数据,如下所示:

item 1 - from table 1
item 2 - from table 1
item 3 - from table 1 - but select only max value of item 3 from table 1
item 4 - from table 2 - but select only max value of item 4 from table 2

我的查询非常简单:

select
    a.item 1,
    a.item 2,
    b.item 3,
    c.item 4
from table 1 a
left join (select b.key_item, max(item 3) from table 1, group by key_item) b on a.key_item = b.key_item
left join (select c.key_item, max(item 4) from table 2, group by key_item) c on c.key_item = a.key_item

我不确定我从表中拉出一个最大项目的方法是否最有效。假设两个表都超过一百万行。我的实际sql使用这个SQL安装程序永远运行。

编辑:我更改了group by子句以反映所做的评论。我希望它现在有点意义吗?

1 个答案:

答案 0 :(得分:1)

您最好的选择是在table1table2添加索引,如下所示:

ALTER TABLE table1
ADD INDEX `GoodIndexName1` (`key_item`,`item3`)

ALTER TABLE table2
ADD INDEX `GoodIndexName2` (`key_item`,`item4`)

这将允许您使用queries as described in the MySQL documentation来查找包含分组最大值的行,这些行似乎就是您要查找的内容。

您的原始(已修改)查询应该有效:

select
    a.item1,
    a.item2,
    b.item3,
    c.item4
from table1 a
LEFT OUTER JOIN (
    SELECT 
    b.key_item, 
    MAX(item3) AS item3
    FROM table1
    GROUP BY key_item
) b 
ON a.key_item = b.key_item
LEFT OUTER JOIN (
    SELECT 
    c.key_item, 
    MAX(item4) 
    FROM table2
    GROUP BY key_item
) c 
ON c.key_item = a.key_item

如果在添加索引后执行缓慢,请尝试以下操作:

SELECT
    a.item1,
    a.item2,
    b.item3,
    c.item4
FROM table1 a
LEFT OUTER JOIN table1 b
ON b.key_item = a.key_item
LEFT OUTER JOIN table1 larger_b
ON larger_b.key_item = b.key_item
AND larger_b.item3 > b.item_3
LEFT OUTER JOIN table2 c
ON c.key_item = a.key_item
LEFT OUTER JOIN table2 larger_c
ON larger_c.key_item = c.key_item
AND larger_c.item4 > c.item4
WHERE larger_b.key_item IS NULL
AND larger_c.key_item IS NULL

(我只是稍微修改了表名和列名,以便它们符合正确的MySQL语法。)

我处理使用上述结构的查询,并且它们使用我提供的索引非常有效地执行。

也就是说,通常我在bc表上使用INNER JOIN,但我不明白为什么您的查询应该有任何问题。

如果您确实遇到性能问题,请报告每个表的key_item列的数据类型,就好像您尝试加入不同的数据类型一样,通常会导致性能下降。