首页 > 数据库 >为什么MySQL innodb的数据达到亿级别,使用‘select count(*) ’将会特别慢?

为什么MySQL innodb的数据达到亿级别,使用‘select count(*) ’将会特别慢?

时间:2023-08-16 16:58:18浏览次数:42  
标签:count COUNT 缓存 使用 查询 innodb MySQL InnoDB SELECT

当表的数据达到亿级别时,使用 SELECT COUNT(*) FROM table 会变得特别慢,主要是因为以下几个原因:

  1. 全表扫描:SELECT COUNT(*) FROM table 通常会导致全表扫描,除非有一些优化手段被应用(例如使用覆盖索引)。当你执行这样的查询,数据库实际上需要读取表中的每一行以计算总数。亿级别的数据意味着有十亿条记录需要被扫描。

  2. I/O开销:大量的数据页需要从磁盘加载到内存中,这会导致大量的I/O操作。即使数据被缓存,处理这么多数据页仍然需要时间。

  3. 锁竞争:在高并发的环境下,如果其他写操作(如INSERT, UPDATE, DELETE)正在与COUNT操作竞争访问同一个表,那么这可能会导致锁的竞争,从而使COUNT操作更加缓慢。

  4. MVCC与事务:如前所述,InnoDB使用MVCC来管理事务并发性。这意味着在执行COUNT操作时,InnoDB需要考虑可能存在的多个版本的记录。处理这些版本会增加COUNT操作的时间。

  5. 不使用计数器:如前文所提及,InnoDB不维护一个全局的、始终准确的行数计数器。因此,它不能像MyISAM那样快速返回一个预存储的行数值。

  6. 缓存效果:如果大部分数据不在InnoDB的缓冲池中,那么执行查询时需要从磁盘中读取这些数据,这会大大增加查询的执行时间。对于包含大量数据的表,很可能只有部分数据被缓存。

  7. 硬件和配置:服务器的硬件配置(如CPU、内存、磁盘速度和类型)以及MySQL的配置设置也会影响查询的性能。

由于上述原因,当处理大数据量时,通常建议避免频繁地执行 SELECT COUNT(*) FROM table。如果需要持续跟踪记录的数量,可以考虑其他策略,如定期缓存数量、使用分摊策略或使用其他技术来加速计数操作。

 

 

有什么好的优化方案方法?

要加速大表中的 SELECT COUNT(*) 查询,有几种方法和策略可以考虑:

  1. 使用覆盖索引:如果你的查询有一个WHERE条件,确保你为这个条件上的字段创建了索引。例如,如果你经常查询 SELECT COUNT(*) FROM table WHERE status=1,确保 status 列被索引,这将使查询更快。

  2. 缓存结果:

    • 如果数据更新不是很频繁,你可以周期性地执行 SELECT COUNT(*) 查询,然后将结果存储在一个缓存中(如Redis、Memcached等),从而避免每次都进行数据库查询。
    • 对于频繁变化的表,每次插入、删除或更改数据时,可以对一个计数器进行增加或减少,然后将这个计数器的值存储在缓存中。
  3. 使用分区:对大表进行分区可以分散I/O负载,并可能提高某些类型的查询的速度。

  4. 使用摘要表:可以创建一个摘要或汇总表,定期或通过触发器更新它来保持记录数。这种表可以为不同的条件或维度提供预计算的计数。

  5. 硬件升级:提高磁盘I/O(例如,使用SSD)、增加RAM、使用更高效的CPU都可以帮助提高查询的性能。

  6. 调整InnoDB缓冲池:增加InnoDB的缓冲池大小(如果内存允许的话)可以帮助更多的数据页保持在内存中,从而减少从磁盘读取的需要。

  7. 估算行数:如果你不需要完全精确的结果,可以考虑使用 SHOW TABLE STATUS 来获得行数的估计值。但是,请注意,这只是一个近似值。

  8. 并行查询:如果你的表已经分区,可以并行地在每个分区上执行 COUNT(*),然后将结果加在一起。

  9. 使用外部工具:某些数据库管理工具和服务可能提供了加速 COUNT(*) 查询的机制。

  10. 优化查询:确保运行 EXPLAIN 语句来查看查询的执行计划,并根据需要进行调整。

无论采用哪种策略,都要确保定期监控并测试性能,以确保你的解决方案在实际使用中是有效的。

标签:count,COUNT,缓存,使用,查询,innodb,MySQL,InnoDB,SELECT
From: https://www.cnblogs.com/shamo89/p/17635535.html

相关文章

  • MySQL 8.0 参考手册——8.2优化 SQL 语句
    数据库应用程序的核心逻辑是通过SQL语句来执行的,无论是通过解释器直接发出还是通过API在后台提交。本节中的调整指南有助于提高各种MySQL应用程序的速度。指南涵盖读写数据的SQL操作、一般SQL操作的幕后开销,以及数据库监控等特定场景中使用的操作。一、优化 SELECT ......
  • mysql安全设置
    ##securitysettingplugin-load-add=connection_control.soconnection-control=FORCEconnection-control-failed-login-attempts=FORCEconnection_control_min_connection_delay=3600000connection_control_max_connection_delay=3600000connection_control_failed......
  • MySQL 8.0 参考手册——优化
    8.1优化概述数据库性能取决于数据库级别的几个因素,例如表、查询和配置设置。这些软件结构在硬件级别上产生CPU和I/O操作,您必须最小化和尽可能有效地进行这些操作。在改进数据库性能时,您首先应学习软件的高级规则和指南,并使用执行时间测量性能。随着您成为专家,您将了解更多内部发......
  • MySQL之Explain
    执行计划输出中各列详解tableEXPLAIN语句输出的每条记录都对应着某个单表的访问方法,该条记录的table列代表着该表的表名这个查询语句只涉及对sys_user表的单表查询,所以EXPLAIN输出中只有一条记录,其中的table列的值是sys_user,表明这条记录是用来说明对sys_user表的单表访问......
  • mysql 5.6 升级到 5.7 教程
    一、下载mysql5.7包  链接:https://pan.baidu.com/s/1ZBA1P6Yxq1clWS1ZZ9YzMw?pwd=yknx提取码:yknx 将下载文件解压后创建mysql.ini,并放入以下内容[mysqld]event_scheduler=onport=3306basedir=D:\mysql\XXXdatadir=D:\mysql\XXX\datamax_connection......
  • MySQL8.0 JSON的对比、排序和索引
    (目录)JSON的对比和排序JSON值可以通过=,<,<=,>,>=,<>,!=,<=>操作符来进行对比JSON不支持BETWEEN,IN(),GREATEST(),LEAST(),可以通过将JSON转换为其他数据类型来使用这些操作符。JSON值的对比在两个级别上进行,先进行数据类型的对比,如果类型相同,再进行值的对比。类型可以......
  • SQLite与Mysql的语句区别
     SQLite中,TEXT是一个通用的字符数据类型,能够存储任何长度的字符串,类似于MySQL的VARCHAR(255)。INTEGER是一个通用的整数数据类型。 此外,SQLite默认情况下是区分大小写的,而MySQL在utf8_general_ci下不区分大小写。如果需要在SQLite中进行不区分大小写的搜索,可以在LIKE操作符中使......
  • 基于微服务+Java+Spring Cloud Vue +UniApp +MySql实现的智慧工地云平台源码
    智慧工地概念智慧工地是一种崭新的工程全生命周期管理理念,是指运用信息化手段,通过对工程项目进行精确设计和施工模拟,围绕施工过程管理,建立互联协同、智能生产、科学管理的施工项目信息化生态圈,并将此数据在虚拟现实环境下与物联网采集到的工程信息进行数据挖掘分析,提供过程趋势预测......
  • JAVA面试之Mysql
    一、什么是三大范式?第一范式(1NF):字段(或属性)是不可分割的最小单元,即不会有重复的列,体现原子性第二范式(2NF):满足1NF前提下,存在一个候选码,非主属性全部依赖该候选码,即存在主键,体现唯一性,专业术语则是消除部分函数依赖第三范式(3NF):满足2NF前提下,非主属性必须互不依赖,消除传递依赖ref:......
  • 图文结合丨带你轻松玩转MySQL Shell for GreatSQL
    一、引言1.1什么是MySQLShell?MySQLShell是MySQL的一个高级客户端和代码编辑器,是第二代MySQL客户端。第一代MySQL客户端即我们常用的MySQL。除了提供类似于MySQL的SQL功能外,MySQLShell还提供JavaScript和Python脚本功能,并包括与MySQL一起使用的API。......