文档章节

MySQL的or/in/union与索引优化 | 架构师之路

kim_o
 kim_o
发布于 2017/07/21 17:58
字数 661
阅读 56
收藏 0
点赞 0
评论 0

原创 2017-07-15 58沈剑 架构师之路

本文缘起自《一分钟了解索引技巧》的作业题。

 

假设订单业务表结构为:

order(oid, date, uid, status, money, time, …)

其中:

  • oid,订单ID,主键

  • date,下单日期,有普通索引,管理后台经常按照date查询

  • uid,用户ID,有普通索引,用户查询自己订单

  • status,订单状态,有普通索引,管理后台经常按照status查询

  • money/time,订单金额/时间,被查询字段,无索引

 

假设订单有三种状态:0已下单,1已支付,2已完成

业务需求,查询未完成的订单,哪个SQL更快呢?

  • select * from order where status!=2

  • select * from order where status=0 or status=1

  • select * from order where status IN (0,1)

  • select * from order where status=0

    union all

    select * from order where status=1

 

结论:方案1最慢,方案2,3,4都能命中索引

 

但是... 

 

一:union all 肯定是能够命中索引的

select * from order where status=0

union all

select * from order where status=1

说明:

  • 直接告诉MySQL怎么做,MySQL耗费的CPU最少

  • 程序员并不经常这么写SQL(union all)

 

二:简单的in能够命中索引

select * from order where status in (0,1)

说明:

  • 让MySQL思考,查询优化耗费的cpu比union all多,但可以忽略不计

  • 程序员最常这么写SQL(in),这个例子,最建议这么写

 

三:对于or,新版的MySQL能够命中索引

select * from order where status=0 or status=1

说明:

  • 让MySQL思考,查询优化耗费的cpu比in多,别把负担交给MySQL

  • 不建议程序员频繁用or,不是所有的or都命中索引

  • 对于老版本的MySQL,建议查询分析下

 

四、对于!=,负向查询肯定不能命中索引

select * from order where status!=2

说明:

  • 全表扫描,效率最低,所有方案中最慢

  • 禁止使用负向查询

 

五、其他方案

select * from order where status < 2

这个具体的例子中,确实快,但是:

  • 这个例子只举了3个状态,实际业务不止这3个状态,并且状态的“值”正好满足偏序关系,万一是查其他状态呢,SQL不宜依赖于枚举的值,方案不通用

  • 这个SQL可读性差,可理解性差,可维护性差,强烈不推荐

 

六、作业

这样的查询能够命中索引么?

  • select * from order where uid in (

             select uid from order where status=0

    )

  • select * from order where status in (0, 1) order by date desc

  • select * from order where status=0 or date <= CURDATE()

 

注:此为示例,别较真SQL对应业务的合理性。

© 著作权归作者所有

共有 人打赏支持
kim_o
粉丝 1
博文 59
码字总数 32160
作品 0
深圳
程序员
如何高效快速地优化MySQL、SQL语句(附源码)

作者介绍 韩锋,宜信技术研发中心数据库架构师。精通多种关系型数据库,曾任职于当当网、TOM在线等公司,曾任多家公司首席DBA、数据库架构师等职,多年一线数据库架构、设计、开发经验。著有...

Yomut ⋅ 2016/10/10 ⋅ 0

[转]关于mysql中explain的那些事儿

explain语法 有两种用法:1.EXPLAIN tbl_name2.EXPLAIN [EXTENDED] SELECT select_options 为了更好的说明它,我们需要建两张表,下面的语句用于创建一张测试用的订单表: CREATE TABLE t_o...

小小人故事 ⋅ 2015/12/15 ⋅ 0

mysql explain用法和结果的含义

//正文开始 重点是第二种用法,需要深入的了解。 先看一个例子: 加上extended后之后: 有必要解释一下这个长长的表格里每一列的含义: id SELECT识别符。这是SELECT的查询序列号 select_typ...

雾妄 ⋅ 2016/12/22 ⋅ 0

mysql explain 显示的列的意义

1、id 语句的执行顺序标识,如果在语句中没有子查询或联合,说明只有一个SELECT,于是这个列显示为1,否则内层的SELECT会顺序编号. 2、select_type 显示了对应的查询是简单还是复杂SELECT,主要...

学习也休闲 ⋅ 2015/12/05 ⋅ 0

使用explain来分析MySQL 查询性能

为了在MySQL中写出高效的SQL脚本,我们的SQL必须时时都要用来检查其执行计划,时时调整。 的使用方法为: 比如下面这条SQL 在MySQL执行完以后如下所示: 下面说一下这些列都代表什么: sele...

古城痴人 ⋅ 2015/08/19 ⋅ 0

MySQL查询优化-explain

一、MySQL 查询优化器是如何工作的 MySQL 查询优化器有几个目标,但是其中最主要的目标是尽可能地使用索引,并且使用最严格的索引来消除尽可能多的数据行。最终目标是提交 SELECT 语句查找数据...

dirgee ⋅ 2014/04/15 ⋅ 0

MySQL查询优化-explain

一、MySQL 查询优化器是如何工作的 MySQL 查询优化器有几个目标,但是其中最主要的目标是尽可能地使用索引,并且使用最严格的索引来消除尽可能多的数据行。最终目标是提交 SELECT 语句查找数据...

天空之风 ⋅ 2014/04/15 ⋅ 2

优化案例 | 分区表场景下的SQL优化

导读 有个表做了分区,每天一个分区。 该表上有个查询,经常只查询表中某一天数据,但每次都几乎要扫描整个分区的所有数据,有什么办法进行优化吗? 待优化场景 有一个大表,每天产生的数据量...

iMySQL | 老叶茶馆 ⋅ 2017/04/11 ⋅ 0

开发人员MySQL调优-实战篇0-explain详解

本来应该先发这篇的,现在才发现漏掉了 项目中SQL优化流程 1.开发人员具备一定的SQL优化基本功 2.在开发阶段,每条写的SQL在测试环境看看他的执行计划 3.上线后让DBA收集查询比较慢的SQL 4.通...

特拉仔 ⋅ 06/13 ⋅ 0

优化案例 | CASE WHEN进行SQL改写优化

导读 今天给大家分享一个通过SQL改写而独辟蹊径的SQL优化案例 待优化场景 发现SLOW QUERY LOG中有下面这样一条记录: 实话说,看到这个SQL我也忍不住想骂人啊,究竟是哪个脑残的XX狗设计的?...

iMySQL | 老叶茶馆 ⋅ 2017/04/14 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

IDEA创建SpringMVC+Mybatis+Maven项目

视频如下(加载有点慢请见谅,服务器不太好): 视频

影狼 ⋅ 14分钟前 ⋅ 0

前阿里P8架构师:精准定制Java架构师学习计划!

可以说,Java是现阶段中国互联网公司中,覆盖度最广的研发语言,掌握了Java技术体系,不管在成熟的大公司,快速发展的公司,还是创业阶段的公司,都能有立足之地。 有不少朋友问,除了掌握J...

java高级架构牛人 ⋅ 17分钟前 ⋅ 0

zookeper学习

https://blog.csdn.net/u012152619/article/category/6470028

~少司命~ ⋅ 18分钟前 ⋅ 0

Spring MVC ,JSON,JQuery,不懂JQuery,跳过了

/spring-mvc-study/src/main/webapp/course_json.jsp <%@ page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%><!DOCTYPE html PUBLIC "-//W3C//DTD ......

颖伙虫 ⋅ 18分钟前 ⋅ 0

2018上海云栖大会workshop-日志数据采集与分析对接

摘要: 日志数据采集与分析对接 课程描述 通过日志服务采集用户、数据库、业务等访问数据。演示对于业务日志分析与处理,程序日志查询与监控,打通日志与数据仓库对接案例。 日志种类 网站访...

阿里云云栖社区 ⋅ 19分钟前 ⋅ 0

mahout demo

package com.datamine.CollaborativeFiltering.mysql; import org.apache.mahout.cf.taste.impl.neighborhood.NearestNUserNeighborhood; import org.apache.mahout.cf.taste.impl.recommend......

xiaomin0322 ⋅ 20分钟前 ⋅ 0

red hat openstack 12配置要求

安装 openstack 之前,一般要规划整个系统中,到底要多少台机器来参与openstack, 根据rhosp12的官方文档: 最低要求是3台物理机,1台作为director,一台作为 controller ,一台作为computer....

tututu_jiang ⋅ 22分钟前 ⋅ 0

Rocket-Chip在GitHub上的各个源码

在github上通过搜索Rocket-chip可以得到36个结果:其中 https://github.com/freechipsproject/rocket-chip https://github.com/ucb-bar/riscv-boom https://github.com/ucb-bar/fpga-zynq (......

whoisliang ⋅ 27分钟前 ⋅ 0

【HAVENT原创】CentOS 6.5 下 Nginx 的安装与配置

nginx是轻量级的Web服务器、反向代理服务器及邮件服务器,具有占用内存少,并发能力强的优点,已被广泛应用。本文介绍目前最新版本 1.12.2 的安装。 各版本nginx下载地址:http://nginx.org/...

HAVENT ⋅ 33分钟前 ⋅ 0

查看linux系统重启之前的log -- last_kmsg

当 Linux Kernel 出现 BUG 的时候,后走入 panic flow,这个时候由于 Kernel 出现了严重的问题,adbd 也无法响应 adb 连接请求,这个时候想透过读取 Kernel Log Buffer 来看 Kernel Log 是不...

zyzzu ⋅ 34分钟前 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部