mysql 两个子查询很快 ,再连接查询变的很慢,怎么分析其原因

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了mysql 两个子查询很快 ,再连接查询变的很慢,怎么分析其原因相关的知识,希望对你有一定的参考价值。

mysql 两个子查询很快 ,再连接查询变的很慢,怎么分析其原因 :例如

select a.*,b.*
from (select * from test1) a
left jioin (select * from test2) b on b.id=a.id

MySQL 在崩溃恢复时,会遍历打开所有 ibd 文件的 header page 验证数据字典的准确性,如果 MySQL 中包含了大量表,这个校验过程就会比较耗时。 MySQL 下崩溃恢复确实和表数量有关,表总数越大,崩溃恢复时间越长。另外磁盘 IOPS 也会影响崩溃恢复时间,像这里开发库的 HDD IOPS 较低,因此面对大量的表空间,校验速度就非常缓慢。另外一个发现,MySQL 8 下正常启用时居然也会进行表空间校验,而故障恢复时则会额外再进行一次表空间校验,等于校验了 2 遍。不过 MySQL 8.0 里多了一个特性,即表数量超过 5W 时,会启用多线程扫描,加快表空间校验过程。
如何跳过校验MySQL 5.7 下有方法可以跳过崩溃恢复时的表空间校验过程嘛?查阅了资料,方法主要有两种:
1. 配置 innodb_force_recovery可以使 srv_force_recovery != 0 ,那么 validate = false,即可以跳过表空间校验。实际测试的时候设置 innodb_force_recovery =1,也就是强制恢复跳过坏页,就可以跳过校验,然后重启就是正常启动了。通过这种临时方式可以避免崩溃恢复后非常耗时的表空间校验过程,快速启动 MySQL,个人目前暂时未发现有什么隐患。2. 使用共享表空间替代独立表空间这样就不需要打开 N 个 ibd 文件了,只需要打开一个 ibdata 文件即可,大大节省了校验时间。自从听了姜老师讲过使用共享表空间替代独立表空间解决 drop 大表时性能抖动的原理后,感觉共享表空间在很多业务环境下,反而更有优势。
临时冒出另外一种解决想法,即用 GDB 调试崩溃恢复,通过临时修改 validate 变量值让 MySQL 跳过表空间验证过程,然后让 MySQL 正常关闭,重新启动就可以正常启动了。但是实际测试发现,如果以 debug 模式运行,确实可以临时修改 validate 变量,跳过表空间验证过程,但是 debug 模式下代码运行效率大打折扣,反而耗时更长。而以非 debug 模式运行,则无法修改 validate 变量,想法破灭。
参考技术A select a.*, b.* from test1 as a left join test2 as b on a.id=b.id;
因为用了left join,所以在表test2的id列创建索引。如果id在两个表已是主键,那就不用建索引。

[转]解决远程连接mysql很慢的方法

开发某应用系统连接公司的测试服务器的mysql数据库连接打开的很慢,但是连接本地的mysql数据库很快,刚开始认为可能是网络连接问题导致的,在进行 ping和route后发现网络通信都是正常的,而且在mysql机器上进行本地连接发现是很快的,所以网络问题基本上被排除了,所以想看看是不是mysql的配置问题。在查询mysql相关文档和网络搜索后,发现了一个配置似乎可以解决这样的问题,就是在mysql的配置文件中增加如下配置参数:

[mysqld]
skip-name-resolve

      在linux下配置文件是/etc/my.cnf,在windows下配置文件是mysql安装目录下的my.ini文件。注意该配置是加在 [mysqld]下面,在更改配置并保存后,然后重启mysql并远程连接测试,一切恢复如初。该参数的官方解释信息如下:

How MySQL uses DNS

When a new thread connects to mysqld, mysqld will spawn a new thread to handle the request. This thread will first check if the hostname is in the hostname cache. If not the thread will call gethostbyaddr_r() and gethostbyname_r() to resolve the hostname.

If the operating system doesn\'t support the above thread-safe calls, the thread will lock a mutex and call gethostbyaddr() and gethostbyname() instead. Note that in this case no other thread can resolve other hostnames that is not in the hostname cache until the first thread is ready.

You can disable DNS host lookup by starting mysqld with –skip-name-resolve. In this case you can however only use IP names in the MySQL privilege tables.

If you have a very slow DNS and many hosts, you can get more performance by either disabling DNS lookop with –skip-name-resolve or by increasing the HOST_CACHE_SIZE define (default: 128) and recompile mysqld.

You can disable the hostname cache with –skip-host-cache. You can clear the hostname cache with FLUSH HOSTS or mysqladmin flush-hosts.

If you don\'t want to allow connections over TCP/IP, you can do this by starting mysqld with –skip-networking.

      根据文档说明,如果你的mysql主机查询DNS很慢或是有很多客户端主机时会导致连接很慢,由于我们的开发机器是不能够连接外网的,所以DNS解析是不可能完成的,从而也就明白了为什么连接那么慢了。同时,请注意在增加该配置参数后,mysql的授权表中的host字段就不能够使用域名而只能够使用 ip地址了,因为这是禁止了域名解析的结果。

 

原文:http://www.cnblogs.com/xiaoxihebei/p/5893887.html

以上是关于mysql 两个子查询很快 ,再连接查询变的很慢,怎么分析其原因的主要内容,如果未能解决你的问题,请参考以下文章

解决远程连接mysql很慢的方法

[转]解决远程连接mysql很慢的方法

带有子查询的 CTE 查询在小型索引表上很慢;如何在 MySQL 上进行优化?

Mysql建了索引查询很慢

MySQL 查询有时很快,有时很慢

sql查询在Hibernate中很慢,在mysql上很快