使用MySQL官方提供的测试数据库来测试多表关联查询与子查询的性能到底谁更胜一筹
写在前面
在程序员的世界里,从来都不缺争论,从世界上最好的语言到世界上最好的IDE再到世界上最好的编辑器,这场没有硝烟的战争从未停止过,当然我自己从来都不会参与其中,也许我是个假程序员,在我看来,最好的东西,从来都不存在,没有最好只有最适合。咳咳~~~好像都点跑题了,是这样,最近跟朋友吃饭的时候,聊到了关于MySQL数据库的多表查询与子查询的性能问题,我的朋友认为多表查询的性能要优于子查询的性能,而我自己认为子查询的性能要优于多表查询,大家都各执一词,谁也没能说服谁,与其这样争论不休、倒不如让数据说话,使用模拟数据进行测试,到底多表查询与子查询谁的性能谁更胜一筹。
导入SQL测试数据
官方文档:https://dev.mysql.com/doc/employee/en/
测试数据库github地址:https://github.com/datacharmer/test_db
1、安装
测试数据使用的是MySQL官方提供的测试数据库,此数据库包含了大约30万的员工数据,280多万条记录,当然所有的数据都是测试数据并非真实数据。数据量并不算多,但用于测试应该是足够了。导入数据也比较简单,首先在github上将test_db-master
下载到本地,解压,切换到test_db-master
目录,运行mysql -u yourusername -p -t < employees.sql
,回车,输入密码即可,类似于下图
图片并没有截全,完整的信息如下:
1 | +-----------------------------+ |
2、测试安装
测试命令如下:
1 | time mysql -u yourusername -p -t < test_employees_sha.sql |
以test_employees_sha.sql
为例,执行time mysql -u mackvord -p -t < test_employees_sha.sql
,显示的信息与官方提供的信息吻合则表示安装没有问题。
1 | +----------------------+ |
在shell
中进入MySQL
模式,查看employees
数据库是否安装成功:
查看数据库的基本信息:
查看employees
表中所有的字段:
1 | mysql> select column_name from information_schema.columns where table_name = "employees"; |
测试
在测试之前,我们先看一下employees数据库的表结构图:
通过观察发现,employees
表与departments
表之间通过dept_emp
这张表连接,那么我们通过一个简单的例子来看一下,同样的需求,使用多表关联查询与子查询所耗费的时间。需求:查询每个部门的编号、名称以及部门的人数
多表查询:
1 | mysql> select d.dept_no,d.dept_name,count(e.emp_no) count |
结果:
子查询:
1 | mysql> select d.dept_no,d.dept_name,temp.count |
结果:
以上只是执行单条查询语句所花费的时间,并没有什么说服力,所以接下来,我们换一种测试的方式。
使用mysqlslap测试
mysqlslap是mysql官方提供的一个用于模拟服务器负载的工具,使用这个工具可以模拟客户端访问服务器,并输出所花费的时间信息,下面我们就以这个工具为例,再次测试上面的sql语句的执行效果。
1、查看帮助信息,在shell中执行: mysqlslap --help
或者 mysqlslap -?
1 | --print-defaults 输出参数列表 |
2、模拟50个客户端,500次并发连接请求
多表查询:
执行以下语句:
1 | mysqlslap -h localhost -P 3306 --concurrency=50 --number-of-queries=500 --create-schema='employees' |
子查询:
执行以下语句:
1 | mysqlslap -h localhost -P 3306 --concurrency=50 --number-of-queries=500 --create-schema='employees' |
通过两次执行的结果来看,多表查询用了将近5分钟,而子查询用了3分钟多一点,虽然两次查询的速度都有点慢,但是貌似子查询的速度要快一点?这样下结论好像太草率了,毕竟这只是查询每个部门的编号、名称以及部门的人数
,对于其他的不同需求,可能编写的sql语句就不一样,那么执行的性能也会有所差异,所以还得看具体问题。OK,文章到此就告一段落了,有时间再继续补充吧。