![MySQL 非常慢,可能是因为存储引擎位于 NAS 上吗?](https://linux22.com/image/757076/MySQL%20%E9%9D%9E%E5%B8%B8%E6%85%A2%EF%BC%8C%E5%8F%AF%E8%83%BD%E6%98%AF%E5%9B%A0%E4%B8%BA%E5%AD%98%E5%82%A8%E5%BC%95%E6%93%8E%E4%BD%8D%E4%BA%8E%20NAS%20%E4%B8%8A%E5%90%97%EF%BC%9F.png)
我们有两台类似规格的 HDD CentOS 7 服务器,用于不同国家的两个不同客户,两个客户都有相同的数据库和相同的索引。
- 客户A:服务器仅运行 MySQL 8,速度极快。查询 X 需要 11 秒才能完成。客户端 A 的数据库比客户端 B 的数据库包含更多记录。
- 客户B:服务器运行的是 LAMP + MySQL 5.7,RAM 和 CPU 正常,查询 X 耗时超过两个小时。在任何其他服务器上花费 X 时间的任何查询,在客户端 B 服务器上花费的时间都是 10 倍。
客户端 B 的 MySQL 存储位于 NAS 上,该 NAS 与服务器的接口为 1GB,IO 速度为 5MB/s。NAS 上只进行读写操作。原因是服务器的 HDD 较小,只有 250GB。这可能是它速度如此缓慢的原因吗?
请注意,如果查询没有连接,则速度很快,但如果有连接,则速度不快。NAS 是否正在尝试缓存某些内容?
答案1
1GB 的服务器接口和 5MB/s 的 IO 速度
5兆字节是1Gb 链路速度很慢。
该服务器有一个小型硬盘,250GB。
对于 Windows Server 来说,这是一个合适的大小,但其中有多少自由的用途?
Windows确实没有就像磁盘空间不足一样,特别是考虑到其中很大一部分空间被分配给了交换(分页)文件!
该服务器有多少可用内存(RAM)?
如果查询没有连接,则速度很快,但如果有连接,则速度不快......
连接不要慢查询会导致......除非这些连接是不是得到索引的正确支持。
我们假设你的查询基本上是
select * from table1 ;
那会速度很慢,因为它必须通过 [慢速] 网络链接将每个数据页拉入内存,然后将其传递给客户端应用程序。当您开始根据索引字段添加“where”子句时,MySQL 就可以开始做一些更聪明的事情。
对于我们来说,了解您正在运行的实际查询及其使用的表的结构是很有用的。
答案2
您的读/写模式是怎样的?
如果写入大量小记录,磁盘和网络延迟就是您的敌人,而 NAS 会增加一层往返网络延迟。
根据您的 NAS,您可能还会遭受写入放大(例如,如果您的数据库认为块为 8k,而 NAS 块为 64k)
这对于读取来说不是什么大问题,因为数据会被缓存在服务器上,但是写入会立即产生延迟费用。
在当今的计算机中,延迟是主要的问题。
https://blog.morizyun.com/computer-science/basic-latency-comparison-numbers.html
答案3
请注意,如果查询没有连接,则速度很快,但如果有连接,则速度不快。可能是 NAS 正在尝试缓存某些东西?
在这种情况下,我首先会考虑被更聪明的算法掩盖的未优化模式,因为 MySQL 8 不存在于 MySQL 5.7 中或在其他设置中不可用。
当你进行连接时,通常应该有一个索引。然后数据库将扫描其中一个表并使用索引从另一个表中挑选匹配的行。
如果不这样做,数据库可能能够在内存中按连接列对表进行排序并合并它们,或者建立内存临时索引,前提是
- 它已经实现了算法,
- 具有足够的内存来缓存数据,并且
- 正确猜测哪种算法更快。
否则它只会回到 O(n²) 算法,这会降低大型表的性能。
所以我的第一个猜测是,对于较新的服务器,上述三个条件得到满足,并且它优化了查询,但对于较旧的服务器,其中一些条件没有得到满足,并且它运行两次嵌套的全扫描。
所以我首先使用解释确保查询使用索引,如果没有,则创建适当的索引。