mysql查询count很慢(MySQL COUNT函数的使用与优化)
mysql查询count很慢
MySQL COUNT函数的使用与优化COUNT 函数做什么用?
COUNT 是一个专用的函数,通常有两种不同的方式:计算值和数据行。值指的是非空(Non-NULL)表达式(NULL表示值缺失)。如果我们在 COUNT的参数中指定了列名或其他表达式,则 COUNT 函数是计算该表达式拥有值的次数。这让很多人困惑,相当一部分的原因是值和 NULL 的概念是模糊的。
另一种 COUNT 的形式是简单地计算结果集的数据行数。这是在 MySQL 知道 COUNT 函数参数的表达式不可能为 NULL 时的计算方式。最为典型的例子是 COUNT(*),你也许会以为这是展开数据表的全部列的一种替代形式。事实上,它会忽略了全部列而仅仅对数据行数进行记数。
一个经常犯的错误是我们在 COUNT 的参数里指定了列名然后以为是对数据行进行计数。如果你是想获取结果中的行数,你应该一直使用 COUNT(*),这会使得你的查询语句意图更明确并且可以避免性能问题。
MyISAM 的“神奇”之处
一个常见的误解是 MyISAM 对于 COUNT 查询来说会非常快。MyISAM 的 COUNT 查询确实快,但这种快的场景十分有限:COUNT()查询并且没有 WHERE 条件时才能达到这样的效果,而实际这种场景很少见。MySQL 能够对这个语句进行优化的原因是存储引擎总是知道数据表的准确行数。如果 MySQL 知道一个列col不可能为 NULL,它也会将 COUNT(col) 转换为 COUNT()来进行优化。
MyISAM在 COUNT 查询中有 WHERE条件、或其他对值进行计数时 并没有“神奇”之处。相比其他存储引擎可能快也可能慢,这取决于很多其他因素。
简单的COUNT优化
当你想要对数据行的索引覆盖不高的情况,又需要统计所有行数量时可以采用 MyISAM 引擎的 COUNT(*)来进行优化。下面的例子使用了标准的世界数据库去展示查找 ID 大于5的城市数量时的优化力度,你写出的SQL 语句可能如下所示:
SELECT COUNT(*) FROM world.City WHERE ID > 5;
如果使用 SHOW STATUS 检查查询的话会发现扫描了4079行。而如果是采用负向条件查询,并且减去那些 ID 小于等于5的城市数量的话,你会发现可以将扫描结果减少到5行。
SELECT (SELECT COUNT(*) FROM world.City) - COUNT(*) FROM world.City WHERE ID <= 5;
这个查询会读取更少的行是因为在查询优化阶段将查询转换为了常量,使用 EXPLAIN 可以看到:
id | select_type | table | rows | Extra |
---|---|---|---|---|
1 | PRIMARY | City | 6 | Using where; Using index |
2 | SUBQUERY | NULL | NULL | Select tables optimized way |
一个常见的问题是如何在一个查询语句中完成对同一列的不同值的数量的查询。例如,你想通过一条查询语句查出不同颜色对应的数量。你不能使用诸如 SELECT COUNT(color = 'blue' OR color='red') FROM items来完成查询,因为这样不会区分出不同颜色相应的数量。而你也不能将颜色放入 WHERE 条件中,例如 SELECT COUNT(*) FROM items WHERE color = 'blue' AND color = 'red'由于颜色本身是互斥的,因此可以用下面的方法解决这一问题:
SELECT SUM(IF(color = 'blue', 1, 0)) AS blue, SUM(IF(color = 'red', 1, 0)) as red FROM items;
还有一种变通的形式是不是要 SUM,而是 COUNT,只是保证了没有值的表达式的判决表达式是 false:
SELECT COUNT(color = 'blue' OR NULL) as blue, COUNT(color = 'red' OR NULL) as red FROM items;
使用近似值
有时候并不需要精确的数量,这个时候就可以使用近似值。在 EXPLAIN优化器中给出的估计行数通常可以满足这种场景,此时可以使用 EXPLAIN 来替代真实的查询。
在很多情况下,一个准确的数量与近似值相比低效很多。一个客户曾经要求统计他们网站的活跃用户数量。用户数量被缓存并每隔30分钟更新一次。这本身就不准确,因此使用估计值是可以接受的。这个查询使用了多个 WHERE 条件去保证不会统计非活跃用户或默认用户(拥有特殊的 ID)。移除这些条件,并稍微修改一下 count 操作就可以变得更高效。一个更进一步的优化是移除不必要的 DISTINCT 操作,从而移除掉一次 filesort 操作。优化后的查询速度更快,且返回了几乎准确的结果。
更复杂的优化
通常来说,COUNT查询很难优化,这是因为它通常需要统计很多行(访问很多数据),在 MySQL 中其他可选的办法是使用覆盖索引。如果那还不够的话,可能需要对整个系统应用架构进行调整了。例如考虑统计数据表,或者使用外部的缓存系统(如 Memcached)。我们往往会面临一个类似的两难问题:快速、准确和简单——你只能从中选择两项!
以上就是MySQL COUNT函数的使用与优化的详细内容,更多关于MySQL COUNT的使用与优化的资料请关注开心学习网其它相关文章!
- mysqlbinlog怎么分析(MySQL中使用binlog时格式该如何选择)
- docker中mysql连接命令(docker 如何修改mysql的root密码)
- docker部署tomcat(Docker安装Tomcat、MySQL和Redis的步骤详解)
- linux安装nacos教程(Nacos配置MySQL8的方法)
- python中怎么连接mysql(python远程连接MySQL数据库)
- mysql8.0.23.0官方安装手册(MySQL8.0.23安装超详细教程)
- mysql 时间戳获取(MySQL时间盲注的五种延时方法实现)
- docker运行redis并操作(Docker安装MySQL和Redis的方法步骤)
- mysql模糊匹配语句(MySQL 数据库 like 语句通配符模糊查询小结)
- mysql如何解析binlog(MySQL的binlog日志使用详解)
- mysql创建数据库教程(MySQL创建数据库并支持中文字符的操作方法)
- mysql拼接多字段作为查询条件(Mysql 实现字段拼接的三个函数)
- mysql常见错误提示及解决办法(MYSQL 无法识别中文的永久解决方法)
- navicatformysql怎么激活(一文读懂navicat for mysql基础知识)
- mysql中json的支持(MySQL中json字段的操作方法)
- mysql的binlog日志详解(MySQL 有关MHA搭建与切换的几个错误log汇总)
- 菲律宾旅游攻略(菲律宾旅游攻略地图)
- 清华大学难考吗(清华大学考研录取分数线)
- 观花盆栽佛肚竹盆景制作及养护(观花盆栽佛肚竹盆景制作及养护)
- 春天养佛肚竹,做好这几件事,叶绿根壮寓意好 越养越旺家(春天养佛肚竹做好这几件事)
- 律界衣品最好,时尚圈学识数高,41岁的Amal堪称现实版的傲骨贤妻(时尚圈学识数高)
- 刘智泰确认出演《Good Wife》 担纲男一号(刘智泰确认出演Good)
热门推荐
- js实现CSS格式化和压缩
- docker给镜像加名称(Alpine Docker镜像字体的问题解决操作)
- iis服务器安装错误(IIS7.0配置过程中出现HTTP 错误 403.14的解决方法)
- springbootdocker详解(Spring Boot 2.4 新特性之一键构建Docker镜像的过程详解)
- 源代码管理中出现重复文件的解决方法
- 为什么dede主页加载不出来(dede中第一次登陆密码错误的解决方法)
- vmware虚拟机搭建服务器(VMware虚拟机建立HTTP服务步骤解析)
- vue图片切换软件(Vue实现简单图片切换效果)
- python模块都是自己的语法(详解Python_shutil模块)
- vue 计算一段时间的月份和天数(vue实现指定日期之间的倒计时)
排行榜
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9