如何有效地选择表中新添加的行?

时间:2011-01-02 13:49:31

标签: sql mysql database performance relational-database

我需要定期更新本地缓存,并添加一些数据库表。表行包含自动递增序列号(SN)字段。缓存也保留了这个数字,所以基本上我只需要获取SN大于我已经拥有的所有行。

SELECT * FROM table where SN > <max_cached_SN>

然而,大多数尝试都不会带来数据(我只需要确保我有一个绝对最新的本地副本)。所以如果这会更有效率,我会徘徊:

count = SELECT count(*) from table;
if (count > <cache_size>)
  // fetch new rows as above

我认为通过索引数字字段进行选择非常有效,所以我喜欢使用count是否有好处。另一方面,这个测试/更新将经常由许多客户完成,因此有动力对其进行优化。

5 个答案:

答案 0 :(得分:3)

  

测试 /更新将经常由许多客户完成

这可能会导致意外的竞争对手缓存生成

我建议

  • 添加到您的表后,将最新的ID添加到队列表
  • 使用like crontab通过检查队列表来触发缓存生成
  • 生成新缓存后,从队列表中删除id

当你强调大多数尝试都不会带来数据时,上述内容只会触发新添加的地方

和队列表概念,甚至可以扩展以进行更新和删除

答案 1 :(得分:2)

我相信

SELECT * FROM table where SN > <max_cached_SN>

会更快,因为select count(*)可能会调用表扫描。只是为了澄清,你永远不会从这个表中删除行吗?

答案 2 :(得分:1)

SELECT COUNT(*)可能涉及扫描(甚至是全扫描),而SELECT ... WHERE SN > constant可以通过SN有效地使用索引,并且查看极少数索引节点就足够了。如果您不需要确切的总数,请不要计算物品,这很贵。

答案 3 :(得分:1)

您无需使用SELECT COUNT(*)

有两种解决方案。

  1. 您可以使用包含temp table的{​​{1}} one field,并在您的表格中插入后创建新的last count of your table并在触发器中添加临时表字段

  2. 您可以使用包含表的Trigger的一个字段的temp table缓存,并在表上插入后创建新的触发器并在触发器中更新临时表字段。

答案 4 :(得分:-1)

真的没那么多

drop table if exists foo;
create table foo
(
foo_id int unsigned not null auto_increment primary key
)
engine=innodb;

insert into foo values (null),(null),(null),(null),(null),(null),(null),(null),(null);

select * from foo order by foo_id desc limit 10;

insert into foo values (null),(null),(null),(null),(null),(null),(null),(null),(null);

select * from foo order by foo_id desc limit 10;