我有以下两个基本SELECT
声明的概要:
select count(*) from mturk_completion;
以下是两人的个人资料:
# My Local machine, using a local db
Status Duration
starting 0.000045
checking permissions 0.000006
Opening tables 0.000015
init 0.000011
System lock 0.000006
optimizing 0.000004
statistics 0.000011
preparing 0.000009
executing 0.000002
Sending data 0.034015 ########
end 0.000012
query end 0.000006
closing tables 0.000011
freeing items 0.000036
cleaning up 0.000010
然后这里是我的 AWS ec2 大型实例上使用 RDS mysql db 的情况:
starting 0.000068
checking permissions 0.000016
Opening tables 0.000028
init 0.000024
System lock 0.000018
optimizing 0.000015
statistics 0.000022
preparing 0.000022
executing 0.000012
Sending data 0.446171 #########
end 0.000036
query end 0.000018
closing tables 0.000023
freeing items 0.00009
cleaning up 0.000013
除了 RDS 实例上的发送数据部分慢十倍以上之外,大多数数字都是可比的! 什么可以解释这一点,我该如何解决这个问题?
以下是RDS实例信息:
答案1
发送数据
该线程正在读取和处理 SELECT 语句的行,并将数据发送到客户端。因为在此过程中发生的操作 此状态倾向于执行大量的磁盘访问(读取),它通常是给定查询的生命周期中运行时间最长的状态。
http://dev.mysql.com/doc/refman/5.0/en/general-thread-states.html
我怀疑磁盘访问速度是差异所在。
在第一次测试中,似乎有一台本地机器连接到带有本地硬盘的本地数据库服务器。在第二次测试中,您将连接到带有远程硬盘(即 EBS)的远程数据库服务器。
EBS(RDS 用于存储)明显慢比实例存储,我想它可能仍然比工作站上未加载的本地磁盘慢(特别是如果您有SSD)。
然而,作为性能损失的补偿,您可以获得 ELB 抽象特性带来的许多好处:
- 能够拍摄实例快照并从快照启动新实例
- 调整磁盘大小的能力
- 改变磁盘性能的能力(通过配置的 IOPS)
- 可以在重启或实例类型更改期间将 RDS 实例透明地移动到新主机
这就是为什么大多数人接受性能损失的原因。
如果性能损失很大,那么您可以尝试以下几种方法:
- 预配置 IOPS
- 使用实例存储在 EC2 上运行您自己的 MySQL 实例。但我不建议这样做,因为如果您的实例停止,很难避免数据丢失,并且如果数据增长,您将无法调整磁盘大小。
- 使用 RAID 中的 EBS 在 EC2 上运行自己的 MySQL 实例
- 水平扩展,如果主服务器上的 IO 成为瓶颈,则添加只读副本
- 在应用程序中实现数据缓存