需要帮助加速聚合SQLite查询

时间:2012-12-09 19:31:11

标签: mysql performance aggregate-functions greatest-n-per-group

我有一个如下定义的表...

CREATE table actions (
  id INTEGER PRIMARY KEY AUTO_INCREMENT,
  end BOOLEAN,
  type VARCHAR(15) NOT NULL,
  subtype_a VARCHAR(15),
  subtype_b VARCHAR(15),
);

我正在尝试查询某个类型的最后一个结束操作是否发生在每个唯一(subtype_a, subtype_b)对上,类似于一个分组(除了SQLite没有说是什么行保证由一组人返回)。

在一个大约1MB的SQLite数据库上,我现在的查询可以超过两秒,但是我需要将其加速到一秒钟以下(因为这将被频繁调用)

示例查询:

SELECT * FROM actions a_out 
WHERE id = 
  (SELECT MAX(a_in.id) FROM actions a_in 
   WHERE a_out.subtype_a = a_in.subtype_a 
     AND a_out.subtype_b = a_in.subtype_b 
     AND a_in.status IS NOT NULL 
     AND a_in.type = "some_type");

如果有帮助,我知道(subtype_a,subtype_b)

的所有独特可能性

例如:

(a,1)
(a,2)
(b,3)
(b,4)
(b,5)
(b,6)

3 个答案:

答案 0 :(得分:1)

从版本3.7.11开始,SQLite guarantees在一个组中返回哪条记录:

  

表单的查询:“SELECT max(x),y​​ FROM table”返回包含最大x值的同一行的y值。

所以可以用更简单的方式实现:

SELECT *, max(id)
FROM actions
WHERE type = 'some_type'
GROUP BY subtype_a, subtype_b

答案 1 :(得分:0)

这会更快吗?

select * from actions where id in (select  max(id) from actions where type="some_type" group by subtype_a, subtype_b);

答案 2 :(得分:0)

这是StackOverflow上频繁出现的greatest-in-per-group问题。

以下是我如何解决它:

SELECT a_out.* FROM actions a_out
LEFT OUTER JOIN actions a_in ON a_out.subtype_a = a_in.subtype_a 
    AND a_out.subtype_b = a_in.subtype_b
    AND a_out.id < a_in.id
WHERE a_out.type = "some type" AND a_in.id IS NULL

如果你有一个索引(type,subtype_a,subtype_b,id),这应该运行得非常快。


另见我对类似SQL问题的回答:

Jan Kneschke的这篇精彩文章:Groupwise Max