-- 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:还有一个本质问题是左连接时左表是主表,无论右表如何,左表的记录都会出现在查询结果中,即无论索引怎么建立,都要遍历左表的所有记录行数;

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

  1. 多表利用DIH批量导入数据并建立索引注意事项

    如果希望同时对多个表进行全文检索,那我们该如何处理呢?利用DIH导入数据并建立索引时.schema.xml中配置了uniqueKey为id <uniqueKey>id</unique ...

  2. oracle 建表id自增长_oracle 左连接、右连接、全外连接、内连接、以及 (+) 号用法...

    Oracle中的连接可分为,内连接(INNER JOIN).外连接(OUTER JOIN).全连接(FULL JOIN),不光是 Oracle,其他很多的数据库也都有这3种连接查询方式. Oracle ...

  3. mysql右表更新左表,mysql优化。左表是25W数据,右表目前小表,但随后是百万,千万,亿级别的表,慢慢增长...

    现在的问题是,我左表是25W数据,一个部门表,右表是部门的积分明细表,现在需要左表连右表,然后用where like 范围查找,如果关键字是全表都有的话,查询出来的结果是25W条数据,查询很慢,大概要 ...

  4. SQL 联表查询的三种方式:左连接、右连接、内连接、默认连接

    数据库表: blog表: user表: 左连接: 以左表为主表,查询出满足条件的内容.查询到的内容是左表全部的内容,和右表满足要求的内容.可能会出行右表内容为为空的可能. select b.id,b. ...

  5. mysql不用left join_MySQL在右表数据不唯一的情况下使用left join的方法_MySQL - join

    一.Join语法概述join 用于多表中字段之间的联系,语法如下:... FROM table1 INNER|LEFT|RIGHT JOIN table2 ON conditionatable1:左表 ...

  6. 表连接查询(多表查询,内连接,左外连接,右外连接)

    什么是表连接:同时对多张表进行查询操作,表与表之间要通过连接条件来连接.一般这个连接条件是主键列是否等于外键列.表连接的主要三种方式是: 连接方式 概念说明 内连接 分为显示内连接和隐式内连接,查询的 ...

  7. sql查询:单表、多表、左连接、外连接、高级查询

    sql查询 一.sql语句 标准SQL包含了4种基本的语句类别: (1)DDL语句,数据定义语句,主要用来定义数据库,表名,字段,例如create,drop,alter. (2)DML语句,数据操作语 ...

  8. mysql 左连接 怎么走索引_数据库索引、左连接、右连接、等值连接

    在MySQL中,主要有四种类型的索引,分别为:B-Tree索引,Hash索引,Fulltext索引(MyISAM 表)和R-Tree索引,本文讲的是B-Tree索引. 一.Mysql索引主要有两种结构 ...

  9. mysql内连接和外连接的区别_数据库左连接、右连接、内连接、全连接区别

    基本定义: left join (左连接):返回包括左表中的所有记录和右表中连接字段相等的记录. right join (右连接):返回包括右表中的所有记录和左表中连接字段相等的记录. inner j ...

最新文章

  1. 如何取消支付宝工资理财
  2. python做电脑软件-PC端数据下载软件开发(Python)
  3. 用Python实现双端队列
  4. QUIC实战(四) 设置应用开机自启动
  5. 如何优化WebAPP性能:从五个层面上彻底优化前端项目性能
  6. 2018-04-08Java编程夯实学习心得(2)
  7. 炸了!我猜了7种颜色,就是没猜中苹果会出姨妈红!
  8. Task Office for mac(任务办公计划管理)
  9. 安装,激活(不更新升级)Navicat premium12.0.24(12.0.18)
  10. 51单片机定时器流水灯控制
  11. 如何查看我的订单-REST的流程API设计案例
  12. SparkStreaming性能调优
  13. matplotlib 绘制图中图
  14. 应届生HR面试需要准备的六大类问题
  15. 墨刀和axure的区别
  16. 数值分析——自适应辛普森积分
  17. 实现对绝对地址赋值详解实现绝对地址开始执行程序详解
  18. echarts中自定义图片的矢量路径设置
  19. 《LeetCode零基础指南》导读
  20. MATLAB 控制baxter机器人相关信息(个人记录--学习用)

热门文章

  1. Codeforces Round #585 (Div. 2) F. Radio Stations 2-sat + 神仙建模
  2. Codeforces Round #694 (Div. 2) E. Strange Shuffle 交互 + 思维分块
  3. YBTOJ洛谷P4869:出现位置(线性基)
  4. CF891C-Envy【可撤销并查集】
  5. P3235-[HNOI2014]江南乐【整除分块,SG函数】
  6. P3308-[SDOI2014]LIS【最小割】
  7. jzoj6316-djq的朋友圈【状压dp】
  8. CF613D-Kingdom and its Cities【虚树,LCA,树链剖分,贪心】
  9. P3830-[SHOI2012]随机树【数学期望,dp】
  10. 牛客练习赛 67——ST表