mysql迁移之后读取速度变慢_如何解决数据库迁移之后变慢的问题
阿里云关系型数据库服务(Relational
Database Service,简称RDS)是一种即开即用、稳定可靠、可弹性伸缩的在线数据库服务。具有多重安全防护措施和完善的性能监控体系,并提供专业的数据库备份、恢复及优化方案,使您能专注于应用开发和业务发展。
使用阿里云关系数据库RDS时,经常听到很抱怨,为什么我的RDS 突然变慢了?相信不少客户在使用RDS 中经常遇到的头疼问题。像这样情况的发生,可能是由于用户操作不当而产生,为了重拾用户对我们RDS的使用信心。 接下来我们通过真实案例来分析一下用户在使用RDS 中变慢的原因:
案例一:
用户从PGSQL迁移到RDS后,发现RDS变慢了。
问题描述:用户的数据库(pgsql)迁移到RDS(mysql)后,发现相同的一条sql 语句,数据量百万级左右,在原来postgreSQL 中执行大概是0.015s,而在RDS 下直接运行是6分20秒左右,执行非常的慢,已经严重的影响用户使用RDS的信心。而实际上,这个问题来自于异构数据库的迁移,由于不同数据库引擎使用的优化算法不同因此同一个SQL的性能表现会存在差异,能过以下操作我们可以进行分析并解决。
可能原因:为什么在用户的数据库上执行只需要0.015s,而到RDS 后变为了6分20s?根据经验,很有可能是SQL 的执行计划改变了,而导致执行时间剧增。
问题排查:通过explain 查看sql 的执行计划,一步一步进行优化。
通过分析,可以从执行计划上分析b 表做了一个全表扫描(执行计划的最后一行),查看b 表中tid 并无索引,所以我们这里可以进行优化,来减少查询过程中关联的行数,从而达到优化:
我们可以看到执行计划中的rows 已经从452变为了2(执行计划的最后一行),
由于mysql 表关联只有nest loop join 这种算法,所以我们可以估算一下这里的优化:
原始执行一:1055789*1*1*1*1*452
扫描的行数
新执行计划二:1055789*1*1*1*1*2
扫描的行数
执行时间:
我们看到执行时间已经由原来的6分20秒下降到了10秒,我们继续优化;
可以看到该sql 的结果集只有8行,但扫描的行数却是非常之大的(1055789*1*1*1*1*2),在优化sql 的非常关键的一点就是优化sql 的执行路程,t=s/v;如果我们能够优化S,那么速度肯定会一下子提上来;那么我们在看看sql 中最后的一句:
-> WHERE EXISTS
-> (SELECT 1 FROM xxxx_test5 b WHERE
a.tid = b.tid);
sql 查询中是要查询出每笔订单的详细信息而不得不关联其他一些表,但是最后的一个exist 限定了我们最后结果的范围,在看看xxxx_test5
这张表有多大:
mysql> SELECT COUNT(*) FROM xxxx_test5;
+----------+
| COUNT(*) |
+----------+
| 403 |
+----------+
1 ROW IN SET (0.00 sec)
mysql> SELECT COUNT(*) FROM xxxx_test5 b
,xxxx_test a WHERE
a.tid = b.tid ;
+----------+
| COUNT(*) |
+----------+
| 8 |
+----------+
1 ROW IN SET (0.42 sec)
两张表关联后只有8行记录,如果我们将订单表xxxx_test 和限定表先做关联,在和其他的一些订单信息表做连接,将会极大减小关联的行数;在进一步改写sql:
分析执行计划,我们发现限定表xxxx_test5做了驱动表,驱动表的变化才是导致问题的最根本原因,扫描的行数:452*1*1*1*1; 这个时候sql 的执行速度将非常快:
Mysql-->;
SELECT a.oi.............
........省去结果
8 ROWS IN SET (0.13 sec)
总结:由于环境迁移,导致sql执行计划改变,这就是RDS变慢的最终原因。
案例二:
用户使用RDS(mssql),经常出现连接超时报错。
问题描述: 使用mssql rds 时不时报错如下,询问是否是连接超过限制导致的?
A network-related orinstance-specific error
occurred while establishing a connection toSQL Server. The server was not found
or was not accessible. Verifythat the instance name is correct and that SQL
Server is configured toallow remote connections. (provider: SQL Network
Interfaces, error:26 – Error Locating
Server/Instance Specified)
可能原因:可能用户的应用程序设计的不是很好,导致数据库锁征用较多;或由于没有建立适当的索引,导致全表扫描,造成数据库等待;
问题排查:通过查看数据库的监控指标,发现在某个时间段有大量的全表扫描,同时数据库的锁争超时,会话数明显增加。
可以看到在15:00的时候有大量的全表扫描,出现了较多的锁超时的情况,同时这个时候也有大量的会话在数据库中,而这个时间恰好也是用户报出错误的时间,在进一步排查,用户的SQL,通过查看mssql 内部的一些视图,来找到对应消耗资源top 5的sql,发现用户频繁的查询一个视图,在视图中有多表连接,但在这些表连接中的字段上没有添加索引,导致了全表扫描,用户视图如下:
CREATE VIEW [dbo].[Vi_xxx]
AS
SELECT ..........
..........
FROM dbo.xxxx_test6 INNER JOIN
dbo.xxxx_test1 ON dbo.xxxx_test5.docID =
dbo.xxxx_test1.docID
INNER JOIN
dbo.xxxx_test2 ON dbo.xxxx_test5.typeID =
dbo.xxxx_test2.typeID
INNER JOIN
dbo.xxxx_test3 ON dbo.xxxx_test5.docID =
dbo.xxxx_test3.docID
INNER JOIN
dbo.xxxx_test4 ON dbo.xxxx_test5.categoryID
=
dbo.xxxx_test4.categoryID
WHERE (dbo.xxxx_test5.isDelete = 0)
通过查看执行计划,发现表上面很多的关联字段没有建立索引,导致全表扫描执行计划如下(有很多的table scan):
总结:用户频繁的查询一个视图,而该视图中表的关联字段上没有索引,导致了大量的全表扫描,累积了大量的会话数,造成数据库性能的下降,应用与数据库之间出现连接错误。
案例三:
隐式转换导致全表扫描
问题描述:用户网站打开缓慢,质疑RDS 性能不好。
可能原因:用户的数据存放在RDS 中,网站访问数据库的时间较长,大多web应用程序设计,SQL没有优化或索引建立的不好导致;
问题排查:通过查看数据库的慢日志,发现大量的慢sql,执行时间超过了2S。
UPDATE USER SET xx=xx+N.N WHERE
account=130000870343 LIMIT 10
SELECT * FROM USER WHERE
account=13056870 LIMIT 10
怀疑在user 表上是否建立索引:
CREATE TABLE `user` (
`id` smallint(5) unsigned NOT NULL
AUTO_INCREMENT,
`account` char(11) NOT NULL COMMENT ‘???’,
…………………….
…………………….
PRIMARY KEY (`id`),
UNIQUE KEY `username` (`account`),
…………………….
) ENGINE=InnoDB CHARSET=utf8 ;
查看执行计划,居然查询使用了全表扫描:
db@3027 16:55:06>explain
select * from user where
account=13056870343;
+—-+————-+——–+——+—————+——+———+——+——+————-+
| id | select_type | table | type |
possible_keys | key | key_len | ref |
rows | Extra |
+—-+————-+——–+——+—————+——+———+——+——+————-+
| 1 | SIMPLE | t_user | ALL | username |
NULL | NULL | NULL | 799 |
Using where |
+—-+————-+——–+——+—————+——+———+——+——+————-+
1 row in set (0.00 sec)
为什么这里会是全表扫描?account 上不是已经建立索引来吗?仔细一看,account 定义为了字符串,而传入的条件为数字,我们知道数字的精度是比字符串高的,所以这里做了隐士转换:
to_number(account)=13056870343
(to_number 为将字符串转换为数字),这样即使account 上有索引,也没法使用了,因此我们将传入的数字改为字符串:
db@3027 16:55:13>EXPLAIN SELECT * FROM
USER WHERE
account='13056870343';
+----+-------------+--------+-------+---------------+----------+------
| id | select_type | TABLE | TYPE |
possible_keys | KEY |
key_len | REF | ROWS | Extra |
+----+-------------+--------+-------+---------------+----------+------
| 1 | SIMPLE | t_user | const | username |
username | 33
| const | 1 | |
+----+-------------+--------+-------+---------------+----------+------
1 ROW IN SET (0.00 sec)
可以看到数据已经能够索引到索引username 了。
总结:由于用户在设计表结构的时候字段定义使用了字符串,而传入的条件却传入了数字造成了隐士转换,这是数据库应用中经常出现的典型问题; RDS足够稳定,但不论在怎么强的数据库,也经不起劣质SQL的挑战,优化sql是长期的一项优化措施。
从上面的三个案例,我们可以总结一下,用户在使用RDS
的时候,发现数据库执行sql 超时,性能较差,连接超时等等这些问题,大多数情况下,是由于应用程序的设计,sql 没有优化,或者索引建立的不好而导致;除非实例不可用(主机down 掉,实例服务停掉,实例由于空间太大而被锁定)而导致用户应用不可用(实例的故障RDS 会有监控报警)。
mysql迁移之后读取速度变慢_如何解决数据库迁移之后变慢的问题相关推荐
- MySql 使用 EF Core 2.0 CodeFirst、DbFirst、数据库迁移(Migration)介绍及示例
dotnet core 2.0 发布已经好几天了,期间也把原来 dotnet core 1.1 的 MVC 项目升级到了 2.0,升级过程还是比较顺利的,变动也不是太多.升级的过程中也少不了 Enti ...
- db2 linux 导入数据_实现DB2数据库迁移之导入步骤在Linux下
今天是要和大家一起讨论的是在Linux操作平台下正确实现DB2数据库迁移之导入的实际操作步骤,如果你对DB2数据库迁移之导入的实际操作步骤,心存好奇的话,以下的文章将会揭开它的神秘面纱. (1)解压 ...
- python访问数据库如何解决高并发_怎样解决数据库高并发的问题
怎样解决数据库高并发的问题?解决数据库高并发使用缓存式的Web应用程序架构.增加Redis缓存数据库.增加数据库索引.页面静态化.使用存储过程.MySQL主从读写分离.分表分库.负载均衡集群. 解决数 ...
- mysql迁移之后读取速度变慢_移动硬盘读取速度突然变慢?教你7个方法解决问题...
如今,许多人更喜欢选择移动硬盘进行数据备份,因为它价格合理,复制速度也高于传统的数据存储介质,如CD或DVD. 但是,有时候,当你在计算机和移动硬盘驱动器之间传输数据时,移动硬盘突然变得非常慢.在这种 ...
- labview提高mysql读取速度_LABVIEW深入探索之MDB数据库写入速度问题。
近日在LABVIEW的群中,看到几次讨论利用队列把采集的数据写入到数据库的问题,讨论非常热烈,但是他们忽略了一个重要的问题,就是数据库的最大写入速度的问题. 一旦你每秒采样数超过一定限度时,无论你采用 ...
- mysql 事务补偿_TCC补偿性策略_彻底学习数据库事务 seata分布式事务 共享 排它锁 死锁 索引 Spring事务 隔离级别等_MySQL视频-51CTO学院...
课程总计41课时,从什么是事务讲起,直到分布式事务解决方案,很的0基础基础与提升系列课程.对于难以理解的知识点,全部用画图+实战的方式讲解. 彻底明白事务的四个特性:原子性.一致性.隔离性.持久性,用 ...
- mysql许多连接错误而被阻止_怎样解决mysql连接过多的错误?
设置max_execution_time 来阻止太长的读SQL.那可能存在的问题是会把所有长SQL都给KILL 掉.有些必须要执行很长时间的也会被误杀. 自己写个脚本检测这类语句,比如order by ...
- mysql按照日期先去重在分组_【巨杉数据库Sequoiadb】【咨询】【数据操作】【聚集查询】在执行聚集查询时,字符类型的字段能否按照实际内容进行分组去重...
[问题描述] 在聚集查询时,能否将字符类型字段按照实际内容进行分组去重呢? 示例: 插入数据包含字符串 db.cs.cl.insert( { a : {"20190101000000&quo ...
- 公司java框架让程序员变笨_框架会使程序员变笨吗?
提示:点击上方"CocoaChina"↑免费订阅 上周,我做了几次面试,要招几名有5年工作经验的高级Java开发人员.但当面试结束后,我感觉到,各种框架(frameworks ...
最新文章
- Linux运维人员成长之路学习书籍推荐
- WeightNet torch
- 粤桂协作从玉农业签约 农业大健康·林裕豪:中国金控粤桂帮扶
- css3动画--位移加阴影
- 完美解决移动Web小于12px文字居中的问题
- 那些年我们踩过的一些坑之 ClickHouse
- Flink-1.13集成hudi-0.10.0
- 边界安全技术简要说明
- 使用CSS 媒体查询功能满足不同屏幕分辨率要求
- git的创建分支与合并分支(5)
- 公司这套架构统一处理try...catch这么香,求求你不要再满屏写了,再发现扣绩效!...
- 资产管理系统测试用例
- 基于最新导则下的生态环境影响评价技术方法及图件制作与案例实践
- DOM ------ 百度换肤
- ecs 导出mysql文件_mysql导出数据库文件
- linux 如何添加字体
- EEE(Energy Efficient Ethernet)-节能以太网
- Java聊天室——一对一模式
- Gitee代码提交 自用
- 状压dp、数位dp、概率dp