mysql - mysql 计算大表中行的性能

标签 mysql bigdata

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

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

select count(id) as total from big_table

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

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

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

最佳答案

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

InnoDB InnoDB does not keep an internal count of rows in a table because concurrent transactions might “see” different numbers of rows at the same time. Consequently, SELECT COUNT(*) statements only count rows visible to the current transaction.

For information about how InnoDB processes SELECT COUNT(*) statements, refer to the COUNT() description in Section 12.20.1, “Aggregate Function Descriptions”.

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

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” 列作为键。

提高并发性

如果您有许多并发 session 插入或删除记录,上述方法确实会产生影响,因为它们需要等待彼此完成计数器的更新。

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

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;

关于mysql - mysql 计算大表中行的性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34512084/

相关文章:

javascript - 访问部分 javascript 数组 (mysqljs)

mysql - Sqoop 语法错误,意外的 tIdentifier

Python + Beam + Flink

hadoop - 在SIG中从SUM获得MAX

mysql - 如何优化这个依赖日期值的 JOIN 查询?

mysql - rs.getMetaData().getColumnName(i) 与 mysql 上的别名列

python - sklearn 聚类 : Fastest way to determine optimal number of cluster on large data sets

google-app-engine - 在 BigQuery 之上设计 API

mysql - 搜索数百万行更好的数据结构

php - 如何全天将系统中的线索平均分配给两方?