mysql Count 查询记录总条数,效率很慢

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了mysql Count 查询记录总条数,效率很慢相关的知识,希望对你有一定的参考价值。

mysql Count 查询记录总条数,效率很慢,2W条记录,需要4S到5S这样...
请问有没有办法优化,,
我看过一种方法是 利用触发器,在单独一张表里保存每张表的总条数.
但是我需要查询总条数是模糊查询例如
select count(*) from table where city like '%扬州%';
请问这样的模糊查询,该如何优化

参考技术A 带条件的count,几乎没有优化的机会,如果写成select count(1) from table where city like '%扬州%'; 会有几乎感觉不到的速度提升本回答被提问者采纳 参考技术B 城市单独建成一个表,你要查询这个表只记录city_id,然后给这个city_id建索引。 参考技术C 尽量不要有条件,可以以此条件生成张临时表,count(*)因该是最优化选择了 参考技术D

我们知道,MySQL 一直依赖对 count(*) 的执行很头疼。很早的时候,MyISAM 引擎自带计数器,可以秒回;不过 InnoDB 就需要实时计算,所以很头疼。以前有多方法可以变相解决此类问题,比如:1. 模拟 MyISAM 的计数器比如表 ytt1,要获得总数,我们建立两个触发器分别对 insert/delete 来做记录到表 ytt1_count,这样只需要查询表 ytt1_count 就能拿到总数。ytt1_count 这张表足够小,可以长期固化到内存里。不过缺点就是有多余的触发器针对 ytt1 的每行操作,写性能降低。这里需要权衡。


2. 用 MySQL 自带的 sql_calc_found_rows 特性来隐式计算

依然是表 ytt1,不过每次查询的时候用 sql_calc_found_rows 和 found_rows() 来获取总数,比如:

    1 row in set, 1 warning (0.00 sec)

    这样的好处是写法简单,用的是 MySQL 自己的语法。缺点也有,大概有两点:1. sql_calc_found_rows 是全表扫。2. found_rows() 函数是语句级别的存储,有很大的不确定性,所以在 MySQL 主从架构里,语句级别的行级格式下,从机数据可能会不准确。不过行记录格式改为 ROW 就 OK。所以最大的缺点还是第一点。

    从 warnings 信息看,这种是 MySQL 8.0 之后要淘汰的语法。

    3. 从数据字典里面拿出来粗略的值


    那这样的适合新闻展示,比如行数非常多,每页显示几行,一般后面的很多大家也都不怎么去看。缺点是数据不是精确值。

    4. 根据表结构特性特殊的取值

    这里假设表 ytt1 的主键是连续的,并且没有间隙,那么可以直接  mysql> select max(id) as cnt from ytt1;    +------+    | cnt  |    +------+    | 3072 |    +------+    1 row in set (0.00 sec)


    不过这种对表的数据要求比较高。


    5. 标准推荐取法(MySQL 8.0.17 建议)

    MySQL 8.0 建议用常规的写法来实现。

    第五种写法是 MySQL 8.0.17 推荐的,也就是说以后大部分场景直接实时计算就 OK 了。MySQL 8.0.17 以及在未来的版本都取消了sql_calc_found_rows 特性,可以查看第二种方法里的 warnings 信息。相比 MySQL 5.7,8.0 对 count(*) 做了优化,没有必要在用第二种写法了。我们来看看 8.0 比 5.7 在此类查询是否真的有优化?MySQL 5.7

    请点击输入图片描述

一次性完成分页查询并且附带数据总条数

通常mysql获取查询记录总数我们使用如下语句:
SELECT COUNT(*) FROM users WHERE k=‘avs‘;
SELECT id FROM goods WHERE k=‘avs‘ LIMIT 10;

但是记录总数总是需要单独的语句来查询,例如在分页查询程序中就有这样的问题,其实mysql可以在一次查询中获取记录和总数的,这就是要使用SQL_CALC_FOUND_ROWS参数,使用方法如下:
SELECT SQL_CALC_FOUND_ROWS goods WHERE k=‘avs‘ LIMIT 10;
SELECT FOUND_ROWS();

这虽然是两个sql语句,但是确是查询一次数据库,效率明显提高了一半!其中SQL_CALC_FOUND_ROWS 告诉Mysql将sql所处理的行数记录下来,FOUND_ROWS() 则取到了这个纪录。

以上是关于mysql Count 查询记录总条数,效率很慢的主要内容,如果未能解决你的问题,请参考以下文章

sql语句分页查询,如何同时返回记录总条数

求mysql+php分页统计总条数的最好方案。

一次性完成分页查询并且附带数据总条数

高速查询hive数据仓库表中的总条数

mysql groupby 后怎么获取每组数据的总条数

mysql查询表中数据总条数的语句怎么写