mysql 千万几数据 查询及其的慢 家索引作用也不大 怎么处理

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了mysql 千万几数据 查询及其的慢 家索引作用也不大 怎么处理相关的知识,希望对你有一定的参考价值。

memcached,redis 读写分离也做了 还是慢

mysql的最佳是单表百万级,一旦上到千万级就慢了,只能分表,分表不行就集群或者换数据库吧。 参考技术A 表分区试下

mysql中的慢查询会不会影响速度

肯定影响的。

常见查询慢的原因常见的话会有如下几种:
1、没有索引或没有用到索引。
PS:索引用来快速地寻找那些具有特定值的记录,所有MySQL索引都以B-树的形式保存。如果没有索引,执行查询时MySQL必须从第一个记录开始扫描整个表 的所有记录,直至找到符合要求的记录。表里面的记录数量越多,这个操作的代价就越高。如果作为搜索条件的列上已经创建了索引,MySQL无需扫描任何记录 即可迅速得到目标记录所在的位置。如果表有1000个记录,通过索引查找记录至少要比顺序扫描记录快100倍。
索引类型:
普通索引:这是最基本的索引类型,没唯一性之类的限制。
唯一性索引:和普通索引基本相同,但所有的索引列只能出现一次,保持唯一性。
主键:主键是一种唯一索引,但必须指定为"PRIMARY KEY"。
全文索引:MYSQL从3.23.23开始支持全文索引和全文检索。在MYSQL中,全文索引的索引类型为FULLTEXT。全文索引可以在VARCHAR或者TEXT类型的列上创建。
2、IO吞吐量小形成了瓶颈。
PS:这是从系统层来分析MYSQL是比较耗IO的。一般数据库监控也是比较关注IO。
监控命令:$iostat -d -k 1 10
参数 -d 表示,显示设备(磁盘)使用状态;-k某些使用block为单位的列强制使用Kilobytes为单位;1 10表示,数据显示每隔1秒刷新一次,共显示10次。
3、内存不足
监控内存使用:vmstat [-n] [延时[次数]]
Memory
swpd: 切换到交换内存上的内存(默认以KB为单位)
• 如果 swpd 的值不为0,或者还比较大,比如超过100M了,但是si, so 的值长期为0,这种情况我们可以不用担心,不会影响系统性能。
free: 空闲的物理内存
buff: 作为buffer cache的内存,对块设备的读写进行缓冲
cache: 作为page cache的内存, 文件系统的cache• 如果 cache 的值大的时候,说明cache住的文件数多,如果频繁访问到的文件都能被cache住,那么磁盘的读IO bi 会非常小。
4、网络速度慢
ping IP -t 查看是否有丢包。
5、一次查询的数据量过大。
比如没有分页查询,一次提取上万条记录。数据库有可能卡死。
6、出现死锁
所谓死锁: 是指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去.
Show innodb status检查引擎状态 ,可以看到哪些语句产生死锁。
执行show processlist找到死锁线程号.然后Kill processNo
7、返回了不必要的行或列
一般查询SQL语句一定要将字段明确指定。而不要使用*进行查询
8、注意UNion和UNion all 的区别。UNION all好
UNION在进行表链接后会筛选掉重复的记录,所以在表链接后会对所产生的结果集进行排序运算,删除重复的记录再返回结果。所以union all的效率肯定要高!
参考技术A

问题

我们有一个 SQL,用于找到没有主键 / 唯一键的表,但是在 MySQL 5.7 上运行特别慢,怎么办?


实验

我们搭建一个 MySQL 5.7 的环境,此处省略搭建步骤。

写个简单的脚本,制造一批带主键和不带主键的表:

执行一下脚本:

现在执行以下 SQL 看看效果:

...

执行了 16.80s,感觉是非常慢了。

现在用一下 DBA 三板斧,看看执行计划:

感觉有点惨,由于 information_schema.columns 是元数据表,没有必要的统计信息。

那我们来 show warnings 看看 MySQL 改写后的 SQL:

我们格式化一下 SQL:

可以看到 MySQL 将

select from A where A.x not in (select x from B) //非关联子查询

转换成了

select from A where not exists (select 1 from B where B.x = a.x) //关联子查询

如果我们自己是 MySQL,在执行非关联子查询时,可以使用很简单的策略:

select from A where A.x not in (select x from B where ...) //非关联子查询:1. 扫描 B 表中的所有记录,找到满足条件的记录,存放在临时表 C 中,建好索引2. 扫描 A 表中的记录,与临时表 C 中的记录进行比对,直接在索引里比对,

而关联子查询就需要循环迭代:

select from A where not exists (select 1 from B where B.x = a.x and ...) //关联子查询扫描 A 表的每一条记录 rA:     扫描 B 表,找到其中的第一条满足 rA 条件的记录。

显然,关联子查询的扫描成本会高于非关联子查询。

我们希望 MySQL 能先"缓存"子查询的结果(缓存这一步叫物化,MATERIALIZATION),但MySQL 认为不缓存更快,我们就需要给予 MySQL 一定指导。

...

可以看到执行时间变成了 0.67s。

整理

我们诊断的关键点如下:

\\1. 对于 information_schema 中的元数据表,执行计划不能提供有效信息。

\\2. 通过查看 MySQL 改写后的 SQL,我们猜测了优化器发生了误判。

\\3. 我们增加了 hint,指导 MySQL 正确进行优化判断。

但目前我们的实验仅限于猜测,猜中了万事大吉,猜不中就无法做出好的诊断。

本回答被提问者采纳

以上是关于mysql 千万几数据 查询及其的慢 家索引作用也不大 怎么处理的主要内容,如果未能解决你的问题,请参考以下文章

mysql中的慢查询会不会影响速度

mysql加了性别变慢

MySQL 千万 级数据量根据(索引)优化 查询 速度

MySQL 千万 级数据量根据(索引)优化 查询 速度

MySql 索引数据结构,千万级大表,关于性别及年龄字段是否需要加索引?

MySql 索引数据结构,千万级大表,关于性别及年龄字段是否需要加索引?