`

mysql 实战 or、in与union all 的查询效率

阅读更多

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

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

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

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

drop table if EXISTS BT;
create table BT(
    ID int(10) NOT NUll,
    VName varchar(20) DEFAULT '' NOT NULL,
    PRIMARY key( ID )
)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

 

DROP PROCEDURE IF EXISTS test_proc;
CREATE PROCEDURE test_proc()
BEGIN
declare i int default 0;
set autocommit = 0;
while i<10000000 do
INSERT INTO BT ( ID,VNAME )  VALUES( i, CONCAT( 'M', i ) );
set i = i+1;
if i%2000 = 0 then
commit;
end if;
end while;
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。

      如以下查询:

select * from bt where bt.VName = 'M98' or bt.id ='9888589'

select * from bt where bt.VName = 'M98'
UNION ALL
select * from bt where  bt.id = '9888589'

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

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

 

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

 

以上测试mysql5.1

 

 

 

 

 

 

  • 大小: 10 KB
  • 大小: 43.8 KB
  • 大小: 97.4 KB
  • 大小: 43 KB
  • 大小: 111.8 KB
5
1
分享到:
评论
6 楼 花易歌 2018-03-23  
如果是不同的字段,2.2里面的or也会多次扫描表,这样的话union all是更快的。
5 楼 itbingqi 2012-12-13  
好文章 谢谢
4 楼 baohanddd 2012-11-26  
如果OR并不是在相同字段上,那么分别为这两个字段创建索引,使用union all会快许多,因为一个查询只使用一个索引。
3 楼 zzj_2046 2012-08-13  
   
2 楼 cfan_haifeng 2012-05-31  
好文章,学习了
1 楼 nsrainbow 2011-10-18  
真是一篇好文章,为我们使用union all 提供了指引!

相关推荐

    MySQL中使用or、in与union all在查询命令下的效率对比

    在MySQL中,OR、IN和UNION ALL是三种常见的SQL查询操作符,它们在不同的场景下各有优劣,效率取决于多种因素,包括索引的存在、数据量、查询条件等。以下是对这些操作符效率的详细分析: 1. **OR操作符**: - 当在...

    MySQL的or、in、union与索引优化

    ### MySQL的or、in、union与索引优化 在数据库查询优化中,索引的使用至关重要,它能显著提升查询速度。本文将基于一个具体的业务场景来探讨在MySQL中使用`union all`、`in`、`or`以及负向查询(如`!=`)时如何有效...

    MySQL UNION 与 UNION ALL 语法与用法.docx

    MySQL UNION 与 UNION ALL 语法与用法 MySQL UNION 语法用于把来自多个 SELECT 语句的结果组合到一个结果集合中。其语法格式为:SELECT column,... FROM table1 UNION[ALL] SELECT column,... FROM table2...其中,...

    MySQL中or、in、union与索引优化详析

    本文主要探讨了`OR`、`IN`、`UNION`操作符以及它们如何与索引交互,以优化查询效率。 首先,我们来看`OR`条件。在旧版的MySQL中,使用`OR`连接的查询通常不会有效利用索引,导致全表扫描,从而降低性能。然而,在...

    MySQL如何使用union all获得并集排序

    在MySQL中,`UNION ALL` 用于合并多个`SELECT`语句的结果集,而这里的重点是如何在合并结果后进行排序。在给定的场景中,我们有一个文章数据表,其中文章的状态通过`PROMOTE_STATUS`字段表示,分别对应0(待发布)、...

    Mysql联合查询UNION和UNION ALL的使用介绍

    本文详细介绍了Mysql的联合查询命令UNION和UNION ALL,总结了使用语法和注意事项,以及学习例子和项目例子,需要的朋友可以参考下

    MYSQL实战45讲(全).zip

    《MYSQL实战45讲》是数据库专家丁奇的一部MySQL技术深度解析著作,它涵盖了MySQL的各个方面,旨在帮助读者深入理解MySQL的核心原理,并提供实践性的指导。本资源包含45讲完整内容,以及作者关于MySQL的心得体会,是...

    两种mysql递归tree查询效率-mysql递归tree

    ### 两种MySQL递归Tree查询效率分析 #### 一、背景与目的 在数据库操作中,经常需要处理具有层级结构的数据。例如,在处理组织结构、文件系统或是地区划分时,通常会采用递归的方式来查询这些层级关系。MySQL作为...

    sql查询优化(提高MySQL数据库查询效率的几个技巧)

    SQL 查询优化(提高 MySQL 数据库查询效率的几个技巧) 在 MySQL 数据库中,查询优化是一个非常重要的方面。在实际应用中,高效的查询可以提高整个系统的性能和响应速度。下面我们将介绍几个提高 MySQL 数据库查询...

    简单了解MySQL union all与union的区别

    union 是对数据进行并集操作,不包括重复行,同时进行默认排序Union all 是对数据进行并集操作,包括重复行,不进行排序举例说明: 创建数据库表: CREATE TABLE `t_demo` ( `id` int(32) NOT NULL, `name` ...

    从 0 开始带你成为MySQL实战优化高手

    【MySQL实战优化高手之路】 MySQL,作为世界上最受欢迎的关系型数据库管理系统之一,对于任何涉及数据库管理、开发或运维的IT专业人士来说,都是一个必备的技能。本资源集合旨在帮助你从零开始,逐步深入理解MySQL...

    从零开始带你成为MySQL实战优化高手PDF.txt

    从零开始带你成为MySQL实战优化高手

    mysql中or是否走索引详解

    有时候,使用`UNION`或`UNION ALL`代替`OR`可以提高查询性能。这将导致两个独立的查询,每个都有自己的索引优化。例如,`SELECT * FROM table WHERE column1 = 'value1' UNION SELECT * FROM table WHERE column2 =...

    MySQL中UNION与UNION ALL的基本使用方法

    在MySQL中,`UNION` 和 `UNION ALL` 是用于合并多个`SELECT`语句结果的两种方式,它们在处理结果集时有着显著的区别。本文将深入探讨这两种操作符的使用方法及其性能差异。 首先,`UNION` 操作符用于合并两个或多个...

    浅析mysql union和union all

    在MySQL数据库中,`UNION` 和 `UNION ALL` 是两种用于合并多个查询结果集的关键字,它们在处理数据时具有不同的特性和性能影响。 首先,`UNION` 关键字用于合并两个或更多 `SELECT` 查询的结果,并且会自动去除重复...

    从 0 开始带你成为MySQL实战优化高手.txt

    《从0开始带你成为MySQL实战优化高手》这一教程旨在帮助读者从零基础开始学习并掌握MySQL数据库优化的核心技能。MySQL作为世界上最受欢迎的关系型数据库管理系统之一,在互联网应用、企业级服务等多个领域发挥着至关...

Global site tag (gtag.js) - Google Analytics