MYSQL 统计 30 万条数据耗时 13 秒,正常吗?如何优化?

嘿嘿,这是众所周知的。
去年我在传输投影时遇到了类似的情况。
当时客户在点击,数据量是3 0万。
结果我跑了控制变量,等了差不多一会儿才得到结果。
1 3 秒确实有点长。

想一想,如果MySQL没有优化的话,如果使用NUME(),默认是扫描全表。
3 0万条数据,如果表中没有缺失条目,硬盘读写就会降低CPU的运算能力。
我记得修炼者只有四核CPU,8 G内存,机械盘。
使用此配置时,全表扫描通常会很慢。
但如果你换了更好的设备,比如我后来换成了1 6 G内存+SSD,速度立刻就不一样了。

还有,如果索引没有正确添加,也会很慢。
我看到了更大的案例,显示有几十万条条目。
但是条件添加错误后,添加了一个字段,却没有列表。
我直接扫了整张桌子,十几秒也没能完成。
最后我改了条件,加上了索引,几秒钟就出结果了。
这就是区别。

那么,您会看到优化是什么样的: 1 . 不要随机生成数字。
如果可以添加条件,比如只统计“活跃”状态,就添加到UB中。
解说立即被缩小。
如果表有主键,计算主键ID比枚举快得多。
当然,这取决于表的结构。
2 .提前计算并保存。
在单个项目中,数据不会经常变化,但我们总是有一定数量的类别。
最后,我们做了一个小表,并使用触发器在每次数据更新时自动更新变化的表。
下次你问的时候,只要检查一下这个小表,几毫秒内就会出来。
这个技巧非常有效,但命题是统计条件是固定的,比如按“类型”或“状态”。
3 .索引添加。
添加常用于条件查询的字段列表,例如 state 和 time_create,如我上面提到的。
如果我们可以创建一个索引屏幕并直接从索引中获取数据,那就更好了。
但这要看你手表的具体情况。
4 .使用缓存。
有些统计结果,比如今天的用户数、订单数,全天变化不大或者变化很大,所以可以放在一个单元格中,就像Redis一样。
下次您需要时,直接进入单元格,不要触摸数据库。
我这里有一个客户使用这种方法,速度统计快了几个数量级。
5 、强烈的仇恨。
如果不起作用,就花更多的钱购买硬件。
将内存增加到足够大,例如增加innod_buffer_pool_size,让数据库可以在更多的内存中工作。
如果把硬盘换成SSD,读取速度立马提升。
上次我换了他们的SSD,跑了全表,从十多秒降到了一两秒。

总的来说,如果没有它,你的 1 3 秒有点慢。
对它进行微调,添加索引,更改查询,使用一些缓存等,它可以将其恢复到秒级甚至千分之一秒级。
要在表结构中执行此操作,需要已知的特征和特定条件。
以上是我的经历,希望对你有帮助。

一文搞懂MySQL索引下推

嗯...指数下推,对吗?它是MySQL开发的技术。
将索引过滤条件传输到存储引擎执行。
这样就可以减少回表次数,减少I/O操作。

核心逻辑如下。
即预先过滤WHERE条件中可以用于存储引擎索引的字段。
传统的方式是存储引擎首先通过索引找到数据,然后返回表,获取整行数据,然后通过服务器层进行过滤。
但ICP允许存储引擎直接过滤掉不满足索引扫描条件的记录。
这样您就不必经常返回表格。

例如,如果我检查 SELECT FROM user WHERE name LIKE 'la%' ANDage=1 8 假设我有一个索引(姓名,年龄)。
在索引扫描阶段,ICP直接过滤掉1 8 岁以下的记录。
这减少了稍后需要返回到表的行数。

与覆盖索引相比,两者都是想减少表返回次数,但实现方法不同。
覆盖索引包含查询该索引所需的所有字段。
示例: SELECT name,age FROM user WHERE.... 这允许您直接从索引获取数据,而不必返回表。
然而,索引下推意味着如果索引不包含所有查询字段,则对索引中的字段进行预过滤,以减少返回表的行数。
就像这个例子中,索引不包含地址字段,但ICP仍然可以通过年龄条件过滤掉一些记录。

2 02 2 年我已经在我们公司用MySQL 8 .0.1 6 版本进行了实验。
创建了一个名为user的表,然后创建了一个共享索引idx_name_age(name,age)。
然后我插入了一些测试数据,大概有几万条。
然后我运行这个查询。

至于结果:当我关闭ICP时,我查看了EXPLAIN结果,发现没有使用索引条件。
那么Handler_read_next的值为3 ,即需要返回该表3 次。
但开启ICP后,EXPLAIN结果显示使用了索引条件,Handler_read_next的值下降为1 ,表明该表只需要返回一次。
这个实验表明,ICP实际上可以显着降低存储引擎访问基表的频率,尤其是在对共享索引的某些列进行模糊查询时。
效果特别明显。

但是,ICP并不是万能的。
适用条件和限制。
首先,它只适用于InnoDB和MyISAM的二级索引。
InnoDB的主键是聚集索引,ICP对其无效。
那么查询类型也必须支持。
range、ref、eq_ref 和 ref_or_null 等访问器都可用,但无法传递与子查询、存储函数、触发器或系统变量相关的条件。
此外,虚拟列限制意味着在虚拟生成的列上创建二级索引时不支持 ICP。
我在 MySQL 8 .0.3 0 之前发现了这一点。
在以后的版本中可能会改变。

从应用场景来看,ICP对于优化常见状态查询效果最好共同指数。
例如,如果使用共享索引(A,B),然后查询 WHERE A LIKE 'x%' AND B=1 ,ICP 可以过滤掉 B 不等于 1 的记录。
但是,请避免在虚拟列或复杂条件(例如:B. 保存的函数)中使用 ICP,因为这可能没有效果。

总的来说,ICP通过将索引过滤条件移至存储引擎层面,有效减少了表返回次数和I/O开销。
对于普通索引的部分列查询效果特别好。
但其实现依赖于存储引擎的支持,还必须满足一定的查询条件。
如果使用得当,可以显着提高查询性能。

MySQL5.5 , 5.6, 5.7, 8.0的新特性

嘿嘿,说起MySQL的发展历史,还真是有趣。
1 9 9 5 年,当MySQL 1 .0版本发布时,它可能只提供给内部员工。
当时,没有人知道它会取得巨大成功。

记得1 9 9 6 年,MySQL跳过了2 .x版本,直接发布了3 .1 1 .1 版本。
也许是为了更快地实现一些新功能。
1 9 9 9 年,MySQL AB成立,并于当年发布了3 .2 3 版本。
该版本集成了BerkeleyDB存储引擎并支持事务,这对于MySQL来说是一大进步。

最近,MyISAM 存储引擎于 2 000 年进行了升级,MySQL 同年使用 GPL 协议开源。
2 002 年,MySQL 4 .0版本发布。
当时的亮点就是InnoDB存储引擎的集成。
该引擎支持行级事务和锁,这在 OLTP 场景中特别有用。

2 005 年,MySQL 5 .0版本发布,增加了游标、存储过程、触发器等功能。
Oracle还收购了InnoDB的开发商Innobase。
2 008 年,Sun以1 0亿美元收购了MySQL AB。
同年,MySQL 5 .1 版本也发布,引入了定时器和分区功能。

2 009 年,甲骨文以7 4 亿美元收购了Sun。
2 01 0年,MySQL 5 .5 版本发布。
该版本显着提高了性能和稳定性。
2 01 3 年,MySQL 5 .6 版本发布。
这个版本被许多人认为是 MySQL 历史上的一个里程碑,因为它是目前生产中使用最广泛的版本。

2 01 5 年,MySQL 5 .7 版本发布,带来了更多新功能。
最后,MySQL 8 .0 版本于 2 01 8 年发布,这个版本引入了很多重大更新,比如性能改进、安全改进等。

顺便查了一下你提到的 MySQL 5 .6 、5 .7 和 8 .0 的新特性。
链接的内容很详细。
你可以检查一下。
对了解MySQL的开发流程会有帮助。
[链接](https://www.cnblogs.com/ivictor/p/9 8 07 2 8 4 .)。
无论如何,这取决于你,我不太擅长这些技术细节,我只是一个门外汉。