【问题标题】:Performance of mysql counting rows in a big tablemysql在大表中计算行数的性能
【发布时间】:2016-04-03 09:33:56
【问题描述】:

这个相当明显的问题几乎没有(找不到任何)可靠的答案。

我从 200 万行的表中进行简单的选择。

select count(id) as total from big_table

我在任何机器上尝试此查询,通常至少需要 5 秒才能完成。这对于实时查询是不可接受的。

我需要获取行的精确值的原因是为了以后进行精确的统计计算。

不幸的是,使用最后一个自动增量值不是一个选项,因为行也会定期删除。

【问题讨论】:

  • 看不到与 mysqli 和/或 PHP 的关系。编辑您的问题以添加相关信息或删除标签。
  • This one 有一个接受的答案。运气不好?
  • @Alfabravo 似乎最佳做法是将值存储在单独的表中并添加更新该值的触发器(InnoDB 案例)。

标签: mysql bigdata


【解决方案1】:

在 InnoDB 引擎上运行时确实会很慢。如section 14.24 of the MySQL 5.7 Reference Manual, “InnoDB Restrictions and Limitations” 中所述,第三个要点:

InnoDB InnoDB 不保留表中的内部行数,因为并发事务可能同时“看到”不同数量的行。因此,SELECT COUNT(*) 语句只计算当前事务可见的行数。

有关 InnoDB 如何处理 SELECT COUNT(*) 语句的信息,请参阅第 12.20.1 节“聚合函数描述”中的 COUNT() 描述。

建议的解决方案是柜台。这是一个单独的表,具有一行和一列,具有当前记录数。它可以通过触发器保持更新。像这样的:

create table big_table_count (rec_count int default 0);
-- one-shot initialisation:
insert into big_table_count select count(*) from big_table;

create trigger big_insert after insert on big_table
    for each row
    update big_table_count set rec_count = rec_count + 1;

create trigger big_delete after delete on big_table
    for each row
    update big_table_count set rec_count = rec_count - 1;

您可以在此处看到fiddle,您应该在其中更改构建部分中的insert/delete 语句以查看效果:

select rec_count from big_table_count;

您可以通过为每个表创建这样的表,或者在上面的计数器表中为每个表保留一行,将其扩展到多个表。然后它将由列 "table_name" 键入。

提高并发性

如果你有很多并发会话插入或删除记录,上述方法确实会产生影响,因为它们需要相互等待才能完成计数器的更新。

一种解决方案是不要让触发器更新相同的单条记录,而是让它们插入一条新记录,如下所示:

create trigger big_insert after insert on big_table
    for each row
    insert into big_table_count (rec_count) values (1);

create trigger big_delete after delete on big_table
    for each row
    insert into big_table_count (rec_count) values (-1);

那么获取计数的方式就变成了:

select sum(rec_count) from big_table_count;

然后,偶尔(例如每天)你应该重新初始化计数器表以保持它的小:

truncate table big_table_count;
insert into big_table_count select count(*) from big_table;

【讨论】:

    【解决方案2】:

    你有索引吗?

    ALTER TABLE big_table ADD INDEX id
    

    你可以检查并尝试添加这个

    【讨论】:

    • id 设置为 PRIMARY KEY... 无论如何我都应该添加 INDEX 吗?
    猜你喜欢
    • 2012-06-14
    • 2010-12-23
    • 1970-01-01
    • 2013-01-05
    • 1970-01-01
    • 2011-09-12
    • 2017-04-09
    • 1970-01-01
    相关资源
    最近更新 更多