在左表或右表的连接字段上建立索引对左、内连接的查询效率的优化情况分析

-- 1、建表

drop table if exists dept_tbl;create table dept_tbl (rcrd_id int unsigned primary key auto_increment comment '记录编号', dept_id int unsigned not null comment '部门编号') engine = innodb default charset=utf8 comment '部门表';drop table if exists emp_tbl;create table emp_tbl (rcrd_id int unsigned primary key auto_increment comment '记录编号', emp_id int unsigned not null comment '员工编号', dept_id int unsigned comment '部门编号') engine = innodb default charset=utf8 comment '员工表';

-- 2、造数据;

insert into dept_tbl(dept_id) values (floor(1+(rand()*20)));insert into dept_tbl(dept_id) values (floor(1+(rand()*20)));insert into dept_tbl(dept_id) values (floor(1+(rand()*20)));insert into dept_tbl(dept_id) values (floor(1+(rand()*20)));insert into dept_tbl(dept_id) values (floor(1+(rand()*20)));insert into dept_tbl(dept_id) values (floor(1+(rand()*20)));insert into dept_tbl(dept_id) values (floor(1+(rand()*20)));insert into dept_tbl(dept_id) values (floor(1+(rand()*20)));insert into dept_tbl(dept_id) values (floor(1+(rand()*20)));insert into dept_tbl(dept_id) values (floor(1+(rand()*20)));insert into emp_tbl(emp_id, dept_id) values (floor(1+(rand()*10000)), floor(1+(rand()*50)));insert into emp_tbl(emp_id, dept_id) values (floor(1+(rand()*10000)), floor(1+(rand()*50)));insert into emp_tbl(emp_id, dept_id) values (floor(1+(rand()*10000)), floor(1+(rand()*50)));insert into emp_tbl(emp_id, dept_id) values (floor(1+(rand()*10000)), floor(1+(rand()*50)));insert into emp_tbl(emp_id, dept_id) values (floor(1+(rand()*10000)), floor(1+(rand()*50)));insert into emp_tbl(emp_id, dept_id) values (floor(1+(rand()*10000)), floor(1+(rand()*50)));insert into emp_tbl(emp_id, dept_id) values (floor(1+(rand()*10000)), floor(1+(rand()*50)));insert into emp_tbl(emp_id, dept_id) values (floor(1+(rand()*10000)), floor(1+(rand()*50)));insert into emp_tbl(emp_id, dept_id) values (floor(1+(rand()*10000)), floor(1+(rand()*50)));insert into emp_tbl(emp_id, dept_id) values (floor(1+(rand()*10000)), floor(1+(rand()*50)));

-- 3、查看索引

 

 

-- 4、左连接

-- 4.1、在左右表的连接字段dept_id上均未建索引的情况下,测试其扫描类型type和扫描行数rows

explainselect a.rcrd_id, a.dept_id, b.rcrd_id, b.emp_id, b.dept_idfrom dept_tbl aleft join emp_tbl bon a.dept_id = b.dept_id

-- 【结论4.1】 在左右表的连接字段dept_id上均未建索引的情况下:左连接使用全表扫描的方式查询左右表;

 

-- 4.2、仅在左表连接字段dept_id上建索引,测试左连接的扫描类型type和扫描行数rows

alter table dept_tbladd key `idx_dept_id` (`dept_id`);explainselect a.rcrd_id, a.dept_id, b.rcrd_id, b.emp_id, b.dept_idfrom dept_tbl aleft join emp_tbl bon a.dept_id = b.dept_id;

--【结论4.2】仅在左表连接字段dept_id上建索引: a表使用了覆盖索引扫描,但扫描行数没变,查询效率得到优化;b表使用了全表扫描,且扫描行数没变,查询效率未得到优化;

 

-- 4.3、仅在右表连接字段dept_id上建索引,测试左连接的扫描类型type和扫描行数rows

alter table dept_tbldrop key `idx_dept_id`;alter table emp_tbladd key `idx_dept_id` (`dept_id`);explainselect a.rcrd_id, a.dept_id, b.rcrd_id, b.emp_id, b.dept_idfrom dept_tbl aleft join emp_tbl bon a.dept_id = b.dept_id;

--【结论4.3】仅在右表连接字段dept_id上建索引: 对右表b上的连接字段建立索引的查询效率优化情况如下:

a表使用了全表扫描,扫描行数没变;b表使用了非唯一性索引单值扫描ref, 且扫描行数为15;对a表的查询效率没有优化,但b表却优化了;

 

-- 4.4、在左表和右表的连接字段dept_id上都建索引,测试左连接的扫描类型type和扫描行数rows

alter table dept_tbladd key `idx_dept_id` (`dept_id`);alter table emp_tbladd key `idx_dept_id` (`dept_id`);explainselect a.rcrd_id, a.dept_id, b.rcrd_id, b.emp_id, b.dept_idfrom dept_tbl aleft join emp_tbl bon a.dept_id = b.dept_id;

-- 【结论4.4】在左表a和右表b的连接字段dept_id上都建索引后: a表使用了覆盖索引扫描,但扫描行数没变;b表使用了非唯一性索引单值扫描ref,扫描行数减少,查询效率得到优化;

 

-- 5、内连接

-- 5.0 查看索引

 

 

-- 5.1、在左右表的连接字段dept_id上均未建索引的情况下,测试其扫描类型type和扫描行数rows

explainselect a.rcrd_id, a.dept_id, b.rcrd_id, b.emp_id, b.dept_idfrom dept_tbl ainner join emp_tbl bon a.dept_id = b.dept_id;

-- 【结论5.1】在左右表上的连接字段均不建索引:a表使用了全表扫描,且总行数100条;b表使用了全表扫描,其总行数700条,这时的查询效率最低;

 

-- 5.2、仅在左表连接字段dept_id上建索引,测试内连接的扫描类型type和扫描行数rows

alter table dept_tbladd key `idx_dept_id` (`dept_id`);explainselect a.rcrd_id, a.dept_id, b.rcrd_id, b.emp_id, b.dept_idfrom dept_tbl ainner join emp_tbl bon a.dept_id = b.dept_id;

-- 【结论5.2】 仅在左表连接字段上建索引: a表使用了覆盖索引扫描,扫描行数为2条,扫描行数减少;b表使用了全表扫描,扫描行数700条,扫描行数没变;故在左表a的连接字段建立索引后,a表的查询效率得到优化;

b表的查询效率没有得到优化;

 

-- 5.3、仅在右表emp_tbl的连接字段dept_id上建索引,测试内连接的扫描类型type和扫描行数rows

alter table dept_tbldrop key `idx_dept_id`;alter table emp_tbladd key `idx_dept_id` (`dept_id`);explainselect a.rcrd_id, a.dept_id, b.rcrd_id, b.emp_id, b.dept_idfrom dept_tbl ainner join emp_tbl bon a.dept_id = b.dept_id;

-- 【结论5.3】仅在右表emp_tbl,即b表的连接字段dept_id上建索引: a表使用了全表扫描,扫描行数100条,查询效率未优化; b表使用了非唯一性索引单值扫描,扫描行数15条,查询效率得到优化;故在右表b的连接字段建立索引后,a表的查询效率没有得到优化;b表的查询效率得到优化;

 

-- 5.4、在左表和右表的连接字段上都建索引,测试内连接的扫描类型type和扫描行数rows

alter table dept_tbladd key `idx_dept_id` (`dept_id`);alter table emp_tbladd key `idx_dept_id` (`dept_id`);explainselect a.rcrd_id, a.dept_id as a_dept_id, b.rcrd_id, b.emp_id, b.dept_id as b_dept_idfrom dept_tbl ainner join emp_tbl bon a.dept_id = b.dept_id;

-- 【结论5.4】 在左表和右表的连接字段上都建索引: 左表即a表使用了覆盖索引,扫描行数100条,查询效率得到优化; 右表即b表使用了非唯一性索引扫描,扫描行数14条,查询效率得到优化;

 

【总结论】

1、对于左连接:

  • 1.1、在左表和右表的连接字段上都不建立索引:左右表都是全表扫描,查询效率最低;
  • 1.2、仅在左表的连接字段上建立索引:左表使用了覆盖索引扫描,扫描行数没变,查询效率得到优化;b表使用了全表扫描,且扫描行数没变,查询效率未得到优化;
  • 1.3、仅在右表连接字段上建索引: 左表表使用了全表扫描,扫描行数没变,查询效率未得到优化;右表使用了非唯一性索引单值扫描ref,扫描行数减少,查询晓得得到优化;
  • 1.4、在左表和右表的连接字段上都建索引后: 左表使用了覆盖索引扫描,扫描行数没变,查询效率得到优化;右表使用了非唯一性索引单值扫描ref,扫描行数减少,查询效率得到优化; 

2、对于内连接

  • 2.1、在左表和右表的连接字段上都不建立索引:左右表都是全表扫描,查询效率最低;
  • 2.2、仅在左表的连接字段上建立索引: 左表使用了覆盖索引扫描,扫描行数减少,查询效率得到优化;右表使用了全表扫描,扫描行数没变,查询效率没有得到优化;
  • 2.3、仅在右表连接字段上建索引: 左表使用了全表扫描,扫描行数没变,查询效率未优化; 右表使用了非唯一性索引单值扫描,扫描行数减少,查询效率得到优化;
  • 2.4、在左表a和右表b的连接字段上都建索引后:左表使用了覆盖索引,扫描行数不变,查询效率得到优化;右表使用了非唯一性索引扫描,扫描行数减少,查询效率得到优化;

3、全文总结论:

【关于左连接的结论补充】

  • 补充1:由于非唯一性索引单值扫描ref 的查询效率高于索引扫描index的查询效率, 所以左连接建议优先在右表的连接字段添加索引,当然最好是左表也加上;
  • 补充2:还有一个本质问题是左连接时左表是主表,无论右表如何,左表的记录都会出现在查询结果中,即无论索引怎么建立,都要遍历左表的所有记录行数;

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/330569.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

并发控制--悲观锁和乐观锁详解

转载自 并发控制--悲观锁和乐观锁详解背景考虑下面两个并发带来的问题:1、丢失更新:一个事务的更新结果覆盖了其它事务的更新结果,即所谓的更新丢失。2、脏读:当一个事务读取其它完成一半事务的记录时,就会发生脏读取。…

如何导出数据到Excel表格

开发工具与关键技术:Visual Studio、MVC 作者:幻奏 撰写时间:2019.5.5我们在日常的生活中常常会看到很多的数据,有时,我们不一定只是在项目里面看到数据,可能我们还要在其他的地方使用,这时我们…

mysql批量插入数据的函数和存储过程

-- 创建函数前,设置 set global log_bin_trust_function_creatorsTRUE; -- 新建函数-产生随机的字符串 drop function if exists rand_str; delimiter ## create function rand_str(n int) returns varchar(255) begin declare chars_str varchar(100) default abc…

打印水晶报表

开发工具与关键技术:Visual Studio、MVC 作者:幻奏 撰写时间:2019.5.8我们在日常生活中常常会打印很多东西,所以我打算讲一下是怎么打印水晶报表的。 打印水晶报表其实和导出差不多,只是有一点不同。打印也用到了多条件…

Java提升篇-事务隔离级别和传播机制

转载自 Java提升篇-事务隔离级别和传播机制问题的提出为了保证并发操作数据的正确性及一致性,SQL规范于1992年提出了数据库事务隔离级别。事务隔离级别分类事务隔离级别由低往高可分为以下几类READ UNCOMMITTED,读取未提交的数据。这是最不安…

多个会话对表加表级读锁和表级写锁后的操作权限分析(表级读锁+表级写锁)

【0】README: 不论是加读锁还是写锁,必须要等到其他数据库连接关闭后才可以进行; 【1】添加表级读锁 1.1)多会话执行的时序操作分析: 1.2)session1执行的具体时序操作; mysql> select * …

如何写登录验证

如何写登录验证 开发工具与关键技术:Visual Studio、MVC 作者:幻奏 撰写时间:2019.05.12我们都知道很多网站都会有登录的界面,目的就是要验证你的账号是否正确,不正确就不能登录,这样就能防止有其他目的的…

关于Java序列化你应该知道的一切

转载自 关于Java序列化你应该知道的一切 什么是序列化 我们的对象并不只是存在内存中,还需要传输网络,或者保存起来下次再加载出来用,所以需要Java序列化技术。 Java序列化技术正是将对象转变成一串由二进制字节组成的数组,可以通…

mysql事务基础+基于innodb的行锁+间隙锁+如何锁定行

【0】README outlines are as follows : 行锁;事务;隔离级别;行锁变表锁;间隙锁;如何锁定一行;行锁总结; 【1】行锁事务存储引擎基础 1、行锁: 偏向于 innodb 存储引擎&#xff0c…

页面跳转、嵌套

页面跳转、嵌套 开发工具与关键技术:Visual Studio、MVC 作者:幻奏 撰写时间:2019.05.16在日常浏览网页的时候,我们常常能看到很多不同样式的网页,其中我们用的最多的应该就是跳转了,点击链接跳转、点击按…

Java高级进阶:自定义ClassLoader

转载自 Java高级进阶:自定义ClassLoader 假如我们的类不在classpath下,而我们又想读取一个自定义的目录下的class,如果做呢? 读取自定义目录的类 示例读取c:/test/com/test.jdk/Key.class这个类。 package com.test.jdk;public…

mysql如何分析sql执行效率和进行效率优化

【0】如何分析mysql中sql执行较慢的问题 步骤1、观察,至少跑一天,看看生产的慢sql情况;步骤2、开启慢查询日志,设置阈值,比如超过5秒钟就是慢sql, 并将它抓取出来;步骤3、explain慢sql分析&…

如何把模型表导入数据库

开发工具与关键技术:Power Designer、SQL 作者:幻奏 撰写时间:2019.05.23事先说明,我只是一个小萌新,我分享的文章是我在学习过程中学到的,不代表全是正确的,所以我要是有什么地方说错了&#x…

解决eclipse中tomcat无法识别maven web项目问题

eclipse工具中导入了maven web项目, 但是tomcat死活都识别不了, maven项目进行了clean install等操作, 但是仍无效, 后在网上搜索到以下答案, 解决问题 1. 右击项目 -> Debug As -> Maven build... 2. 在Goals中填入: -Dwtpversion2.0 eclipse:eclipse 对于WTP(Web Tool…

深入理解CAS算法原理

转载自 深入理解CAS算法原理1、什么是CAS?CAS:Compare and Swap,即比较再交换。jdk5增加了并发包java.util.concurrent.*,其下面的类使用CAS算法实现了区别于synchronouse同步锁的一种乐观锁。JDK 5之前Java语言是靠synchronized关键字保证同…

如何写登录的记住账号

开发工具与关键技术:Visual Studio、MVC 作者:幻奏 撰写时间:2019.05.27上次我把如何登录的代码给写了,却没有写如何记住登录的账号密码,所以现在我就简单的写一下是如何记住账号密码的。 如果我们没写记住密码的话&am…

严重: Error configuring application listener of class org.springframework.web.context.ContextLoaderLis

博主 使用Eclipse 下的Mavn搭建的SSM框架的工程,出现以下错误 严重: Error configuring application listener of class org.springframework.web.context.ContextLoaderListener Java.lang.ClassNotFoundException: org.springframework.web.context.ContextLoad…

java高级应用:线程池全面解析

转载自 java高级应用:线程池全面解析 什么是线程池? 很简单,简单看名字就知道是装有线程的池子,我们可以把要执行的多线程交给线程池来处理,和连接池的概念一样,通过维护一定数量的线程池来达到多个线程的复…

如何用for循环出数据库的数据

开发工具与关键技术:Visual Studio、MVC 作者:幻奏 撰写时间:2019.5.30在客房管理的系统中有很多不同的小格子,它们分别代表了不同的房间,可以动态的显示每间房间的状态,这个就是房态图。有很多系统应该都有…

Maven常见问题之【-Dmaven.multiModuleProjectDirctory system property is not set】

配置jdk时,声明vm参数,如下, 且需要保证 M2_HOME 环境变量已经配置了, 如下: C:\Users\pacoson>echo %M2_HOME% D:\software_cluster\apache-maven-3.3.9 -Dmaven.multiModuleProjectDirectory$M2_HOME