Mysql查询优化之 触发器加中间表 方法优化count()统计大数据量总数问题

    转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/6138288.html

    在上一篇博文我们提到,分页有三种方法。其中,第三种是我们最常用的。然而,在实际应用过程中我们会发现,select count(*) from tname 语句在统计某表内记录总数时,如果表内数据量达到一定规模(比如100W条),这个语句就会执行得非常慢。有什么办法可以加快统计出表内记录总数呢?

    这里,我们需要借助一个中间表来记录数据库内各表记录总数。然后,在我们需要知道某表的记录总数来计算分页数时直接查询中间表获取目的表的记录总数即可。无需把目的表全部查询一次然后逐一统计。

   

    这里有人要问了,这个中间表哪儿来的呢?嘿嘿,无需再用一个文件来定期更新!数据库已经为我们提供了一个很好的工具啦!那就是——触发器。

    触发器是一种特殊的存储过程。一般的存储过程是通过存储过程名直接调用,而触发器主要是通过事件(增、删、改)进行触发而被执行的。其在表中数据发生变化时自动强制执行。所以,我们只需要为每个需要监听的表创建一个触发器,使得该表有增、删操作时,自动对rowsCount中间表里相应的记录进行修改,即可同步更新中间表对各表的记录。

    这里大致讲一下触发器的创建:我用的数据库桌面工具是SQLyog。

    在需要监听的表上右键,选择“创建触发器”,工具会自动生成一些通用的代码如下:

    CREATE
    TRIGGER `数据库名`.`触发器名` BEFORE/AFTER INSERT/UPDATE/DELETE
    ON `数据库名`.`<Table Name>`
    FOR EACH ROW

    BEGIN

    事件发生后执行的代码
    END

监听器有两种:事前执行与事后执行。分别对应上面的BEFORE/AFTER.

事件类型有三种:插入、修改、删除

监听对象为:数据库名.表名

事件发生后代码:触发器的主体部分。用于响应监听对象发生所监听的事件前/后所执行的sql操作。比如:修改某中间表中的数据来记录监听表的变化。

    实例:为admin表创建监听器,在admin表有数据插入后,激活触发器执行,更新pagecount中间表中,tablename为admin的那条记录的total属性,因为插入了一条记录,所以total+1.

   

    CREATE
    TRIGGER `counter` AFTER INSERT ON `admin` 
    FOR EACH ROW    
    BEGIN
    UPDATE pagecount SET total=total+1 WHERE tablename = 'admin';
    END;

 

  

转载于:https://www.cnblogs.com/ygj0930/p/6138288.html

<think>嗯,用户想了解如何在MySQL查询表的数据量。这个问题看起来挺常见的,可能用户需要统计数据库中的记录数,或者进行性能优化。首先,我需要回忆一下MySQL中常用的方法。 首先想到的是使用COUNT(*)函数,这是最直接的方式。比如SELECT COUNT(*) FROM table_name; 但要注意,这个方法在MyISAM引擎下可能会很快,因为引擎会缓存行数,但InnoDB的话,因为MVCC机制,实际会扫描索引来得到准确的行数,数据量大时可能较慢。 然后,用户可能不知道不同存储引擎的行为差异,所以需要解释清楚。另外,如果用户只是要估算数据量,可能可以用SHOW TABLE STATUS命令,里面的Rows字段,不过这个对于InnoDB是估算值,不一定准确。这时候需要提醒用户注意这个区别。 还有EXPLAIN语句,执行EXPLAIN SELECT * FROM table_name 后,结果中的rows字段也是一个估计值,可能和实际有出入。这个方法适用于快速估算,但精确度不高。 另外,记得提到information_schema数据库里的TABLES表,特别是TABLE_ROWS列。例如SELECT TABLE_ROWS FROM information_schema.TABLES WHERE TABLE_SCHEMA = 'database_name' AND TABLE_NAME = 'table_name'; 但同样,这个对于InnoDB是近似值,可能不准确。 用户可能会有疑问,为什么不同的方法结果不同,这时候需要解释存储引擎的影响,以及COUNT(*)的实际执行方式。可能需要比较不同方法的优缺点,帮助用户根据场景选择合适的方法。 还有,如果用户需要频繁查询数据量,尤其是大表,可以建议他们使用缓存或者定期更新统计信息,比如ANALYZE TABLE命令,这样SHOW TABLE STATUS或者information_schema的数据会更准确一些。 需要确保语法正确,比如表名和数据库名是否正确,是否需要反引号,权限问题等。另外,中文回答要清晰,分步骤说明,可能还要给出示例代码,用$$...$$格式? 不过根据系统指令,行内数学表达式用$...$,独立公式用$$...$$,但这里可能不需要数学公式,主要是SQL语句。但用户问题关于MySQL查询,所以应该用代码块?不过用户层的指令里没有提到代码格式,可能需要用反引号或者适当的方式呈现SQL语句。 可能需要分点回答,先介绍各种方法,再比较它们的优缺点,使用场景,注意事项等。确保用户了解不同方法的适用情况,比如精确计数还是估算,性能差异等。 最后检查是否有遗漏的方法,比如使用触发器或者外部工具来维护计数,但可能超出用户当前问题的范围,可以暂时不提,除非用户后续有更深入的问题。</think>在 MySQL查询表的数据量(即记录总数)有以下几种常用方法,根据场景和需求选择合适的方式: --- ### 1. **使用 `COUNT(*)` 函数(精确统计)** ```sql SELECT COUNT(*) FROM table_name; ``` - **特点**: - 返回表的**精确行数**。 - 对于 InnoDB 引擎,会实时扫描索引计算行数(大数据量时可能较慢)。 - 对于 MyISAM 引擎,直接读取缓存值(速度极快)。 - **适用场景**:需要精确结果的查询。 --- ### 2. **通过 `SHOW TABLE STATUS`(估算统计)** ```sql SHOW TABLE STATUS LIKE 'table_name'; ``` - **特点**: - `Rows` 字段显示表的**估算行数**(可能与实际值存在偏差)。 - 对于 InnoDB 引擎,该值是采样统计的近似值。 - **适用场景**:快速获取估算值,无需精确结果。 --- ### 3. **查询 `information_schema` 系统表(估算统计)** ```sql SELECT TABLE_ROWS FROM information_schema.TABLES WHERE TABLE_SCHEMA = 'your_database_name' AND TABLE_NAME = 'your_table_name'; ``` - **特点**: - `TABLE_ROWS` 是估算值,与 `SHOW TABLE STATUS` 结果一致。 - 适用于通过 SQL 直接获取多表的数据量统计。 --- ### 4. **使用 `EXPLAIN` 分析查询(估算统计)** ```sql EXPLAIN SELECT * FROM table_name; ``` - **特点**: - 结果中的 `rows` 字段是优化器估算的扫描行数。 - 不执行实际查询,速度快,但精度较低。 --- ### 对比与注意事项 | 方法 | 精确性 | 性能 | 适用场景 | |-----------------------|-------------|------------|-----------------------| | `COUNT(*)` | 精确 | 可能较慢 | 需要精确统计时 | | `SHOW TABLE STATUS` | 估算 | 极快 | 快速估算、InnoDB 大表 | | `information_schema` | 估算 | 快 | 编程集成或批量查询 | | `EXPLAIN` | 粗略估算 | 极快 | 查询优化分析 | --- ### 附说明 - **InnoDB 的统计机制**: InnoDB 的估算值可能因未及时更新统计信息而产生偏差,可通过以下命令刷新统计信息: ```sql ANALYZE TABLE table_name; ``` - **性能优化**: 若需频繁查询大表数据量,建议将统计结果缓存到业务层,避免直接调用 `COUNT(*)`。 根据需求选择合适的方法即可!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值