当前位置:首页 > 数码 > 优化数据统计的终极指南-MySQL-提升查询性能的秘诀 (优化数据统计工具)

优化数据统计的终极指南-MySQL-提升查询性能的秘诀 (优化数据统计工具)

admin5个月前 (04-14)数码34

在业务场景中,我们经常需要统计当前已有的业务数据,例如商品库内商品的数量、每天的用户订单数量等。此时,我们需要使用统计功能来实现。

count()实现方式

对于不同的数据库引擎,count()的实现逻辑也不同。

InnoDB

InnoDB利用多版本控制机制支持事务,一行记录会记录多个MVCC。统计行数这一行为与隔离级别直接相关。在RR级别下,每一行记录都要判断自己是否对这个会话可见,每个会话也会执行增删改操作,导致每个事务统计的行数不一致。因此,对于count()来说,InnoDB只好把数据一行行读出来,对可见的行进行统计。因此,InnoDB不能像MyISAM引擎一样在磁盘保存数据行树。

以下是一个示例:

提升查询性能的秘诀 CREATE TABLE test ( id INT NOT NULL AUTO_INCREMENT, name VARCHAR(255) NOT NULL, PRIMARY KEY (id) );

执行以下语句创建表并插入数据:

INSERT INTO test (name) VALUES ('test1'); INSERT INTO test (name) VALUES ('test2'); INSERT INTO test (name) VALUES ('test3');

执行count()统计行数:

SELECT COUNT() FROM test;

输出结果为:

3

在这个示例中,会话C没有显示开始事务,因此每条语句都是独立事务。由于AB会话都没有提交事务,因此,AB的修改对C不可见。事实上,InnoDB对count()做了一定优化,由于InnoDB是索引组织表,主键索引树的叶子节点是数据,普通索引树的叶子阶段是主键值,因此,普通索引树比主键索引树小很多。执行count()的逻辑就是遍历,因此,MySQL优化器会选择最小的索引树用于遍历,相对于每次都读取所有的数据行,只是遍历主键,自然IO开销要小的多。

因此,在保证逻辑正确的前提下,尽量减少扫描的数据量,是数据库系统设计的通用法则之一。

还有一个显示行数的命令为:showtablestatus;也会显示表的行数,但是这里的rows是预估值,这个预估值是根据随机采集计算出来的,MySQL随机取N页数据,计算出每页中不同记录数,求取平均值后乘以总页数得到的就是预估值。这个预估值是否接近真实值,取决于索引字段区分度、索引数据页紧凑程度、是否存在页分裂、索引空洞等元素。这个预估值也是造成MySQL选错索引的原因。

如何实现计数逻辑

使用缓存系统统计计数

如果是一般场景,使用缓存系统执行计数是满足需求的,即使说,由于服务集群异常重启导致数据丢失,但是可以再次扫描一次表获取表的总数。但是如果是非常严谨的场景(银行统计实际支付的订单数据等),那可能有如下的问题。

  1. 第一个是缓存可能会丢失数据,即使是开启持久化,还是存在丢失数据可能性。redis持久化有RDB和AOF两种方式;RDB按照备份策略,比如60秒1000个k-v被修改,备份过程中宕机,那么这个阶段的所有更新都会丢失;AOF按照备份策略,比如endfsyncalways策略,同步记录所执行的指令到日志文件,但是它的日志和mysql的WAL不同,它是写后日志,可能指令执行后写日之前宕机,那这个数据就丢失了,虽然丢失数据较少且概率较低,但依然存在这个可能。
  2. 第二个是数据一致性保证问题,Redis和MySQL是两个数据源,可以看成是一种分布式一致性的问题,而分布式一致性由于不能保证原子性,因此一般只能保证最终一致性,不能保证实时一致性。

数据一致性问题

数据一致性问题目前可分为三类:

  1. 主从不一。解决办法:半同步复制可以保证实时的一致性,因为写时写主和从之后才响应,只不过这样写的并发上不去;其他访问有强制读主、消息中间件路由读主和缓存是否失效读主;
  2. 数据库与缓存的不一。解决办法:读操作直接读缓存,写操作先更新到数据库,淘汰缓存(程序需要保证两个操作的原子性,如果淘汰失败,则发一条小实现异步淘汰).由于该key的缓存已经清理掉,那么下次读的时候需要先读数据库,在重建缓存.由于redis是单线程,保证了一个操作的原子性.可以通过设置appendfsyncalways来保证每次操作都把该操作记录并落盘到aof文件里(不过一般redis该值为everysec),毕竟使用redis的目的不是为了保证acid.还是要根据业务来选择。
  3. 一个事务跨多个节点或者多种数据库(分库分表和银行转账这种例子)。目前好像都是通过2pc,3pc来保

1.存储引擎的选择如果数据表需要事务处理,应该考虑使用InnoDB,因为它完全符合ACID特性。 如果不需要事务处理,使用默认存储引擎MyISAM是比较明智的。 并且不要尝试同时使用这两个存储引擎。 思考一下:在一个事务处理中,一些数据表使用InnoDB,而其余的使用MyISAM.结果呢?整个subject将被取消,只有那些在事务处理中的被带回到原始状态,其余的被提交的数据转存,这将导致整个数据库的冲突。 然而存在一个简单的方法可以同时利用两个存储引擎的优势。 目前大多数MySQL套件中包括InnoDB、编译器和链表,但如果你选择MyISAM,你仍然可以单独下载InnoDB,并把它作为一个插件。 很简单的方法,不是吗?2.计数问题如果数据表采用的存储引擎支持事务处理(如InnoDB),你就不应使用COUNT(*)计算数据表中的行数。 这是因为在产品类数据库使用COUNT(*),最多返回一个近似值,因为在某个特定时间,总有一些事务处理正在运行。 如果使用COUNT(*)显然会产生bug,出现这种错误结果。 3.反复测试查询查询最棘手的问题并不是无论怎样小心总会出现错误,并导致bug出现。 恰恰相反,问题是在大多数情况下bug出现时,应用程序或数据库已经上线。 的确不存在针对该问题切实可行的解决方法,除非将测试样本在应用程序或数据库上运行。 任何数据库查询只有经过上千个记录的大量样本测试,才能被认可。 4.避免全表扫描通常情况下,如果MySQL(或者其他关系数据库模型)需要在数据表中搜索或扫描任意特定记录时,就会用到全表扫描。 此外,通常最简单的方法是使用索引表,以解决全表扫描引起的低效能问题。 然而,正如我们在随后的问题中看到的,这存在错误部分。 5.使用“EXPLAIN”进行查询当需要调试时,EXPLAIN是一个很好的命令,下面将对EXPLAIN进行深入探讨。

免责声明:本文转载或采集自网络,版权归原作者所有。本网站刊发此文旨在传递更多信息,并不代表本网赞同其观点和对其真实性负责。如涉及版权、内容等问题,请联系本网,我们将在第一时间删除。同时,本网站不对所刊发内容的准确性、真实性、完整性、及时性、原创性等进行保证,请读者仅作参考,并请自行核实相关内容。对于因使用或依赖本文内容所产生的任何直接或间接损失,本网站不承担任何责任。

标签: MySQL

“优化数据统计的终极指南-MySQL-提升查询性能的秘诀 (优化数据统计工具)” 的相关文章

Java开发者的MySQL数据库版本管理策略-从规划到部署的全面指南 (java开发工程师)

Java开发者的MySQL数据库版本管理策略-从规划到部署的全面指南 (java开发工程师)

数据库是软件开发中常用的关系型数据库之一。版本管理是保障数据库稳定性和可靠性的重要方面。本文将介绍针对 Java 开发者的 MySQL 数据库版本管理策略,包括版本控制工具选择、数据库脚本管理、变...

MySQL-一探究竟-核心模块揭秘 (mysql-bin文件可以删除吗)

MySQL-一探究竟-核心模块揭秘 (mysql-bin文件可以删除吗)

Undo Segment Caching To improve the efficiency of undo segmentallocation, InnoDB caches some un...

主从复制原理简介-MySQL (主从复制原理mysql)

主从复制原理简介-MySQL (主从复制原理mysql)

主从复制(Master-SlaveReplication)是一种数据复制技术,用于在多个数据库主机之间的数据同步。在主从复制架构中,一个主机被设置为主主机(Master),充任数据源,其余主机被设...

全面指南-如何解决-MySQL-主从延时问题 (全面指导)

全面指南-如何解决-MySQL-主从延时问题 (全面指导)

一、什么是主从延时? 主从延时,是指从数据库从主数据库复制数据时产生的时间差。它会导致从库中的数据与主库不一致。 二、为什么会主从延时? 1. 主从复制原理 MySQL的...

使用-数据库并自动发送备份文件到指定邮箱-K8s-定期备份-MySQL (使用数据库的命令)

使用-数据库并自动发送备份文件到指定邮箱-K8s-定期备份-MySQL (使用数据库的命令)

简介 本文档描述了一个使用脚本来监控服务器高占用率进程并通过电子邮件发送警报的项目。本文还探讨了使用相同机制备份数据库的可能性。 技术 Python psuti...

EXPLAIN-代价模型-MySQL-浅析-提早预知索引优化战略-优化查问性能-告别自觉经常使用 (explain)

EXPLAIN-代价模型-MySQL-浅析-提早预知索引优化战略-优化查问性能-告别自觉经常使用 (explain)

背景 在中,当咱们为表创立了一个或多个索引后,通常须要在索引定义成功后,依据详细的数据状况口头EXPLN命令,才干观察到数据库实践经常使用哪个索引、能否经常使用索引。这使得咱们在参与新索引之...

MySQL-实现非中断亿级数据处理的秘密 (mysql-bin文件可以删除吗)

MySQL-实现非中断亿级数据处理的秘密 (mysql-bin文件可以删除吗)

MySQL 在海量数据管理方面表现得非常出色,能够存储上亿级别的数据,同时还具有极高的数据可靠性,几乎不会发生数据丢失的情况。这一强大的特性离不开 MySQL 的两大日志系统:binlog 和 r...