MySQL多表查询合并结果和内连接查询

1、使用union和union all合并两个查询结果:select 字段名 from tablename1 union select 字段名 from tablename2;
 
注意这个操作必须保证两张表字段相同,字段数据类型也相同,再针对结果统一排序操作等。另外,使用union的时候会去除重复(相同)的记录?,而union all则不会。
create table table_new
select * from
(
SELECT * FROM DB.table1
union all
SELECT * FROM DB.table2
) as t
group by key1,key2 collate utf8_bin
order by key1,key2;
  1. 在数据库查询中,默认是不区分大小写的。那如何让查询结果区分大小写呢?collate utf8_bin放在like前后都可以。

  2. select * from user where name like "A\%B%"  collate utf8_bin;

          或者  select * from user where name  collate utf8_bin like "A\%B%" ;

注:下边的几个连接查询涉及到笛卡尔积的概念,即如果存在两张表,第一张记录数为n条,另一张表的记录数为m条,那么笛卡尔积得出的记录数就是n*m条;如果第一张表的字段数为a个,另一张的字段数为b个,则笛卡尔积得出的字段数就是a+b个。
 
2、使用natural join自然连接:前提是两张表有相同的字段:(这个操作会去掉重复的字段)
 
对于这个查询,我的理解是:保留这两张表中关联字段(例如这里的depart_id)都存在的数据,去掉只有一个表中有的:
如上述内容中,company中有四条数据,而emp中有7条,结果不论哪个放前边都只出来六条,因为company中depart_id为4的,emp中没有,而emp中depart_id为5的,company中又没有。
 
 
3、inner join on等值连接查询:
 
这个操作在我理解,和上边的自然连接区别就在于没有去掉重复的字段,还有更加的灵活,不需要有相同字段名的字段:
 
4、inner join on不等值连接查询:
 
对于这个查询,我的理解就是,他是“=”查询的补集,即这个查询的结果集 = 笛卡尔积结果集  减去“=”查询的结果集;本例中,company有4条记录,emp有7条记录,笛卡尔积是4*7=28条记录;“=”查询的结果是6条记录,一次"!="查询就应该是其余的22条记录。
 
5、从上边的操作中可以拓展出另一种查询:字连接查询,即实际只有一张表,用重命名的方式当成两张来用:
 
可以看到,根据笛卡尔积,这里应该有4*4=16条结果,但是因为有了条件,就筛选出了四条
 
 
 
 
 
 
 
 
 mysql 实战 or、in与union all 的查询效率

OR、in和union all 查询效率到底哪个快。

网上很多的声音都是说union all 快于 or、in,因为or、in会导致全表扫描,他们给出了很多的实例。

但真的union all真的快于or、in?本文就是采用实际的实例来探讨到底是它们之间的效率。

1:创建表,插入数据、数据量为1千万【要不效果不明显】。

  1. drop table if EXISTS BT;
  2. create table BT(
  3. ID int(10) NOT NUll,
  4. VName varchar(20) DEFAULT '' NOT NULL,
  5. PRIMARY key( ID )
  6. )ENGINE=INNODB;

该表只有两个字段 ID为主键【索引页类似】,一个是普通的字段。(偷懒就用简单的表结构呢)

向BT表中插入1千万条数据

这里我写了一个简单的存储过程【所以你的mysql版本至少大于5.0,俺的版本为5.1】,代码如下。

注意:最好

INSERT INTO BT ( ID,VNAME )  VALUES( i, CONCAT( 'M', i ) );---1

修改为

INSERT INTO BT ( ID,VNAME )  VALUES( i, CONCAT( 'M', i, 'TT' ) );---2

修改原因在

   非索引列及VNAME使用了联合进行完全扫描请使用1 

非索引列及VNAME使用了全表扫描请使用2 

  1. DROP PROCEDURE IF EXISTS test_proc;
  2. CREATE PROCEDURE test_proc()
  3. BEGIN
  4. declare i int default 0;
  5. set autocommit = 0;
  6. while i<10000000 do
  7. INSERT INTO BT ( ID,VNAME )  VALUES( i, CONCAT( 'M', i ) );
  8. set i = i+1;
  9. if i%2000 = 0 then
  10. commit;
  11. end if;
  12. end while;
  13. END;

就不写注释呢,挺简单的。

存储过程是最好设置下innob的相关参数【主要和日志、写缓存相关这样能加快插入】,俺没有设置插入1千万条数据插了6分钟。

部分数据如下:1千万数据类似

2:实战

2.1 :分别在索引列上使用 or、in、union all

我们创建的表只有主键索引,所以只能用ID做查询呢。我们查 ID 为 98,85220,9888589的三个数据各个耗时如下:

时间都为0.00,怎么会这样呢,呵呵所有查询都是在毫秒级别。

我使用其他的工具--EMS SQL Manager  for mysql

查询显示时间为

93 ms, 94ms,93 ms,时间相差了多少几乎可以忽略。

然后我们在看看各自的执行计划

这里要注意的字段type 与ref字段

我们发现union all 的所用的 type【type为显示连接使用了何种类型】 为ref 而or和in为range【ref连接类型优于range,相差不了多少】,而查询行数都一样【看rows字段都是为3】。

从整个的过程来看,在索引列使用常数or及in和union all查询相差不了多少。

但为什么在有的复杂查询中,再索引列使用or及in 比union all 速度慢很多呢,这可能是你的查询写的不够合理,让mysql放弃索引而进行全表扫描。

2.2:在非索引列中使用 or、in及union all。

我们查 VNAME 为 M98,M85220,M9888589的三个数据各个耗时如下:

我们发现为啥union all查询时间几乎为 or 和in的三倍。

这是为什么呢,我们先不说,先看看三个的查询计划。

这里我们发现计划几乎一样。

但我们要注意扫描的此时对于 or及in 来说 只对表扫描一次即rows是列为9664782。

而对于union all 来说对表扫描了三次即rows的和为9664782*3。

这也是为什么我们看到union all 为几乎为三倍的原因。

备注: 如果使用存储过程使用第二sql该执行计划所有的type列 为 all,其实这个是我最想演示的,但现在已经快写完毕了才发现问题将错就错呢。

3:总结

 3.1:不要迷信union all 就比 or及in 快,要结合实际情况分析到底使用哪种情况。

     3.2:对于索引列来最好使用union all,因复杂的查询【包含运算等】将使or、in放弃索引而全表扫描,除非你能确定or、in会使用索引。

    3.3:对于只有非索引字段来说你就老老实实的用or 或者in,因为 非索引字段本来要全表扫描而union all 只成倍增加表扫描的次数。

    3.4:对于及有索引字段【索引字段有效】又包含非索引字段来时,按理你也使用or 、in或者union all 都可以,

       但是我推荐使用or、in。

如以下查询:

  1. select * from bt where bt.VName = 'M98' or bt.id ='9888589'
  2. select * from bt where bt.VName = 'M98'
  3. UNION ALL
  4. select * from bt where  bt.id = '9888589'

该两个查询速度相差多少 主要取决于 索引列查询时长,如索引列查询时间太长的话,那你也用or或者in代替吧。

3.5: 以上主要针对的是单表,而多表联合查询来说,考虑的地方就比较多了,比如连接方式,查询表数据量分布、索引等,再结合单表的策略选择合适的关键字。 

个人观点仅供参考、需要结合实际数据用例测试选择合适的关键字.......................

MySQL多表查询合并结果union all,内连接查询的更多相关文章

  1. mysql——多表——内连接查询

    内连接查询:可以查询两个或者两个以上的表,当两个表中存在表示相同意义的字段时,可以通过该字段来连接这两个表: 当该字段的值相等时,就查询出该记录. 前期准备两个表: ), d_id ), name ) ...

  2. MySQL (五)--连接查询简介、 交叉连接、 内连接、外连接、自然连接、温馨小提示

    1 连接查询简介 将多张表(可以大于2)进行记录的连接(按照某个指定的条件进行数据拼接). 最终结果:记录数可能会有变化,字段书一定会增加(至少两张表的合并). 连接查询:join,使用方式:左表 j ...

  3. Mysql高手系列 - 第11篇:深入了解连接查询及原理

    这是Mysql系列第11篇. 环境:mysql5.7.25,cmd命令中进行演示. 当我们查询的数据来源于多张表的时候,我们需要用到连接查询,连接查询使用率非常高,希望大家都务必掌握. 本文内容 笛卡 ...

  4. MySQL数据操作与查询笔记 • 【第7章 连接查询】

    全部章节   >>>> 本章目录 7.1 内连接查询 7.1.1 交叉连接(笛卡尔积) 7.1.2 内连接查询概要 7.1.3 内连接案例 7.1.4 自然连接 7.2 多表连 ...

  5. mysql内连接查询之自连接

    连接查询: 当查询数据时,通过连接操作查询出存放在多个表中的不同数据,当两个或者多个表中存在相同意义的字段时, 便可以通过这些字段对不同的表进行连接查询. 自连接: 如果在一个连接查询中,涉及的两个表 ...

  6. HQL的内连接查询

    /** * HQL的内连接查询 * String hql="from Customer c inner join fetch c.linkmans"; */ @Test publi ...

  7. mysql常用基础操作语法(八)~~多表查询合并结果和内连接查询【命令行模式】

    1.使用union和union all合并两个查询结果:select 字段名 from tablename1 union select 字段名 from tablename2: 注意这个操作必须保证两 ...

  8. mysql求交集:UNION ALL合并查询,inner join内连接查询,IN/EXISTS子查询

    两个要求交集的表(列)的结构要一致,对应的字段数,字段类型都应该相同:将两个数据的数据列用 UNION ALL 关键字合并:将上面的所有需要比较的列 GROUP BY :最后 HAVING COUNT ...

  9. Mysql学习总结(24)——MySQL多表查询合并结果和内连接查询

    1.使用union和union all合并两个查询结果:select 字段名 from tablename1 union select 字段名 from tablename2: 注意这个操作必须保证两 ...

随机推荐

  1. 小解POJO、PO、BO、VO

    POJO :plain ordinary java object 无规则简单java对象 一个中间对象,可以转化为PO.DTO.VO. 一个简单的Java类,这个类没有实现/继承任何特殊的java接口 ...

  2. Julia出现错误ERROR: LoadError: syntax: try without catch or finally

    因项目要求进行机器学习数据可视化,要求尝试使用Julia,在此,记录下遇到的坑,仅为记录效果.后续陆续更新. 问题一:关于LightML库中的坑:ERROR: LoadError: syntax: t ...

  3. echart 柱状图 两个纵轴坐标 刻度不一样

    在使用echart的过程中, 有的时候柱状图会使用两个纵坐标, 如果两个纵坐标的最大值是一样的还好,这样刻度也会一样. 但是多数情况下最大值是不一样的, 这样就造成了,刻度线很乱,显示不均匀. 解决办 ...

  4. JS观察者设计模式:实现iframe之间快捷通信

    观察者设计模式又称订阅发布模式,在JS中我们习惯叫做广播模式,当多个对象监听一个通道时,只要发布者向该通道发布命令,订阅者都可以收到该命令,然后执行响应的逻辑.今天我们要实现的就是通过观察者设计模式, ...

  5. 计算机系统结构总结_Memory Review

    这次就边学边总结吧,不等到最后啦 Textbook: <计算机组成与设计——硬件/软件接口>  HI <计算机体系结构——量化研究方法>       QR Ch3. Memor ...

  6. flask之上下文管理

    简单来说,falsk上下文管理可以分为三个阶段: 1.请求进来时,将请求鞋底的相关数据放入上下文管理中进行管理 2.在视图函数中,要去上下文管理中取值 3.请求响应之后,要将上下文管理中的数据清除 详 ...

  7. 使用axios发送ajax请求

    1.安装 npm install axios 2.在Home.vue中引入 import axios from 'axios' export default {   name: 'Home',   c ...

  8. Vue中如何引入第三方icon库(阿里巴巴矢量图标库)

    1.进入阿里巴巴矢量图标库: 2.新建项目 3.前缀注意不要跟element-ui自带的icon(el-icon)重名就ok 4.创建完成后,去阿里选自己要使用的图标,加入购物车           ...

  9. setState总结

    react中的setState特点: 是异步操作函数: 组件在还没有渲染之前, this.setState 还没有被调用: 批量执行 State 转变时让 DOM 渲染更快(相对比一个一个的setSt ...

  10. nice - 改变执行程序的优先级

    总览 (SYNOPSIS) nice [OPTION]... [COMMAND [ARG]...] 描述 (DESCRIPTION) 以 调整过的 调度优先级 运行 COMMAND. 如果 没给出 C ...