Mysql 范围查询优化
Range查询:用单独的Index的一个或多个index值来检索表的子集行数据,当然包含多个index。
1:一个index (单一部分)的range access 方法:(eg : 指的这种key (column1 ))
单独的index,index值间隔可以方便的由对应的where子句的条件表示,所有我们称值为range条件而不是间隔;
单独index的range条件的定义:
1.1:对于btree和hash索引,index和一个常量值通过 =, <=>,in(),is null,或者 IS not null操作符做比较;
1.2:另外,对于Btree索引,index和一个常量值通过 <,>,<=,>=,between,!=,或者<>操作符做比较;
1.3: 对于所有类型的index,多范围条件通过 or and关键字组合形式;
'常量值'在之前的描述中意味着:
2.1: 查询字符串的常量形式;
2.2: const 或者system表的一列(也只有一列)的自连接(join);
2.3: 不相关子查询的结果;
2.4: 有上面类型子表达式完全组成的任意表达式;
where子句范围查找的例子:
SELECT * FROM t1
WHERE key_col > 1
AND key_col < 10; SELECT * FROM t1
WHERE key_col = 1
OR key_col IN (15,18,20); SELECT * FROM t1
WHERE key_col LIKE 'ab%'
OR key_col BETWEEN 'bar' AND 'foo';
一些非常量值可能在传播阶段转换为常量;
Mysql尝试对于在where子句中的任何可能的index提取range condition,在提取过程中,不能构造的范围条件被舍去,产生重叠的条件被组合,产生空范围的条件被舍去。
如下:
SELECT * FROM t1 WHERE
(key1 < 'abc' AND (key1 LIKE 'abcde%' OR key1 LIKE '%b')) OR
(key1 < 'bar' AND nonkey = 4) OR
(key1 < 'uux' AND key1 > 'z');
key1为index, nonkey非index;
key1的提取过程如下:
1:从原始的where子句开始:
(key1 < 'abc' AND (key1 LIKE 'abcde%' OR key1 LIKE '%b')) OR
(key1 < 'bar' AND nonkey = 4) OR
(key1 < 'uux' AND key1 > 'z')
2:舍去nokey = 4和key1 like ‘%d’,因为他们不能用作范围scan,正确的舍去方法是用true代替她们,
(key1 < 'abc' AND (key1 LIKE 'abcde%' OR TRUE)) OR
(key1 < 'bar' AND TRUE) OR
(key1 < 'uux' AND key1 > 'z')
3: 以下条件总是true or false;
1:(key1 LIKE 'abcde%' OR TRUE)
is always true
2:(key1 < 'uux' AND key1 > 'z')
is always false
(key1 < 'abc' AND TRUE) OR (key1 < 'bar' AND TRUE) OR (FALSE)
4: 去掉不必要的true 和false条件:
(key1 < 'abc') OR (key1 < 'bar')
5:组合那些重叠的区间成一个:
(key1 < 'bar')
范围条件的提取算法可以处理内嵌的and /or任意深度的构造,他的数去不依赖与他们出现在where子句中的顺序;
2:多part index的范围查询:
index的多个部分的范围条件是上面的扩展,被一个或几个key元组来限制条件:
eg: 一个联合索引定义:key1(key_part1,key_part2,key_part3),key元组以key order显示如下:
key_part1 key_part2 key_part3
NULL 1 'abc'
NULL 1 'xyz'
NULL 2 'foo'
1 1 'abc'
1 1 'xyz'
1 2 'abc'
2 1 'aaa'
条件
定义的区间:key_part1
= 1
(1,-inf,-inf) <= (key_part1,key_part2,key_part3) < (1,+inf,+inf)
这区间包括第四,第五,第六元组。
相对,条件 key_part3
= 'abc'不能定义一个单独的区间并且不能被区间scan方法使用(最左前缀index);
3:多值的区间优化:
以下col_name 是index 列:
col_name IN(val1, ..., valN)
col_name = val1 OR ... OR col_name = valN
如果col_name 等于这些值中的任意一个返回true,
1:如果col_name 为unique index,则范围的行评估为1,因为最多一个值只能对应一行;
2:否则,优化器估计范围行数得使用index潜入和index的统计信息;
index潜入,优化器植入一个潜入在每个range的结尾并且用该范围的行数来估计,eg:
,优化器植入两个潜入在每个区间中来估计行数;index潜入提供精确的行估计,但是当表达式中的比较值越多,每个潜入对需要话费更多时间。用index统计信息缺乏精确但是较快。col_name
IN (10, 20, 30)
30727 rows in set (5.37 sec) mysql> explain select * from employees where first_name like 'm%' ;
+----+-------------+-----------+------+---------------+------+---------+------+--------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-----------+------+---------------+------+---------+------+--------+-------------+
| 1 | SIMPLE | employees | ALL | idx_fn_ln | NULL | NULL | NULL | 299290 | Using where |
+----+-------------+-----------+------+---------------+------+---------+------+--------+-------------+
1 row in set (0.00 sec) mysql> explain select * from employees where first_name like 'mart%' ;
+----+-------------+-----------+-------+---------------+-----------+---------+------+------+-----------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-----------+-------+---------------+-----------+---------+------+------+-----------------------+
| 1 | SIMPLE | employees | range | idx_fn_ln | idx_fn_ln | 16 | NULL | 1635 | Using index condition |
+----+-------------+-----------+-------+---------------+-----------+---------+------+------+-----------------------+
1 row in set (0.00 sec)
第一个条件查找从执行计划上看走的扫表(all),where条件得到的结果为所以数据行的1/10;第二条增加like条件的匹配精度,走的ICP range查找,得到的数据行大约是1/30,mysql
会根据查找的数据范围(多少)决定走index range查找还是直接扫表(all)
mysql> desc select * from employees where first_name like 'ma%' and last_name like 'he%';
+----+-------------+-----------+-------+---------------+-----------+---------+------+-------+-----------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-----------+-------+---------------+-----------+---------+------+-------+-----------------------+
| 1 | SIMPLE | employees | range | idx_fn_ln | idx_fn_ln | 34 | NULL | 38174 | Using index condition |
+----+-------------+-----------+-------+---------------+-----------+---------+------+-------+-----------------------+
1 row in set (0.04 sec)
mysql> desc select * from employees where first_name like 'ma%' or last_name like 'he%';
+----+-------------+-----------+------+---------------+------+---------+------+--------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-----------+------+---------------+------+---------+------+--------+-------------+
| 1 | SIMPLE | employees | ALL | idx_fn_ln | NULL | NULL | NULL | 299290 | Using where |
+----+-------------+-----------+------+---------------+------+---------+------+--------+-------------+
1 row in set (0.02 sec)
mysql> desc select * from employees where first_name in('mart','mori','moon');
+----+-------------+-----------+-------+---------------+-----------+---------+------+------+-----------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-----------+-------+---------------+-----------+---------+------+------+-----------------------+
| 1 | SIMPLE | employees | range | idx_fn_ln | idx_fn_ln | 16 | NULL | 710 | Using index condition |
+----+-------------+-----------+-------+---------------+-----------+---------+------+------+-----------------------+
1 row in set (0.02 sec)
mysql> explain select * from employees where emp_no = 11;
+----+-------------+-------+------+---------------+------+---------+------+------+-----------------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+------+------+-----------------------------------------------------+
| 1 | SIMPLE | NULL | NULL | NULL | NULL | NULL | NULL | NULL | Impossible WHERE noticed after reading const tables |
+----+-------------+-------+------+---------------+------+---------+------+------+-----------------------------------------------------+
1 row in set (0.01 sec)
Mysql发现where条件不可能成立 ,返回null
Mysql 范围查询优化的更多相关文章
- php mysql 一个查询优化的简单例子
PHP+Mysql是一个最经常使用的黄金搭档,它们俩配合使用,能够发挥出最佳性能,当然,如果配合Apache使用,就更加Perfect了. 因此,需要做好对mysql的查询优化.下面通过一个简单的例子 ...
- WebAPI调用笔记 ASP.NET CORE 学习之自定义异常处理 MySQL数据库查询优化建议 .NET操作XML文件之泛型集合的序列化与反序列化 Asp.Net Core 轻松学-多线程之Task快速上手 Asp.Net Core 轻松学-多线程之Task(补充)
WebAPI调用笔记 前言 即时通信项目中初次调用OA接口遇到了一些问题,因为本人从业后几乎一直做CS端项目,一个简单的WebAPI调用居然浪费了不少时间,特此记录. 接口描述 首先说明一下,基于 ...
- MySQL in查询优化
https://blog.csdn.net/gua___gua/article/details/47401621 MySQL in查询优化<一> 原创 2015年08月10日 17:57: ...
- 查询优化 | MySQL慢查询优化
Explain查询:rows,定位性能瓶颈. 只需要一行数据时,使用LIMIT1. 在搜索字段上建立索引. 使用ENUM而非VARCHAR. 选择区分度高的列作为索引. 采用扩展索引,而不是新建索引 ...
- MySQL 慢查询优化
为什么查询速度会慢 1.慢是指一个查询的响应时间长.一个查询的过程: 客户端发送一条查询给服务器 服务器端先检查查询缓存,如果命中了缓存,则立可返回存储在缓存中的结果.否则进入下一个阶段 服务器端进行 ...
- MySQL SQL查询优化技巧详解
MySQL SQL查询优化技巧详解 本文总结了30个mysql千万级大数据SQL查询优化技巧,特别适合大数据里的MYSQL使用. 1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 ...
- 关于mysql的查询优化
由于工作原因,最近甲方客户那边多次反应了他们那边的系统查询速度慢,经过排除之后,发现他们那边的数据库完全没有用到索引,简直坑得一笔,通过慢查询日志分析,为数据表建立了适当的索引之后,查询速度明显的提高 ...
- 《MySQL慢查询优化》之SQL语句及索引优化
1.慢查询优化方式 服务器硬件升级优化 Mysql服务器软件优化 数据库表结构优化 SQL语句及索引优化 本文重点关注于SQL语句及索引优化,关于其他优化方式以及索引原理等,请关注本人<MySQ ...
- MySQL 的查询优化
说起 MySQL 的查询优化,相信大家收藏了一堆奇技淫巧:不能使用 SELECT *.不使用 NULL 字段.合理创建索引.为字段选择合适的数据类型..... 你是否真的理解这些优化技巧?是否理解它背 ...
- MySQL慢查询优化
MySQL数据库是常见的两个瓶颈是CPU和I/O的瓶颈,CPU在饱和的时候一般发生在大量数据进行比对或聚合时.磁盘I/O瓶颈发生在装入数据远大于内存容量的时候,如果应用分布在网络上,那么查询量相当大的 ...
随机推荐
- Node.js 蚕食计划(五)—— Koa 基础项目搭建
Koa 是由 Express 原班人马打造的超轻量服务端框架 与 Express 相比,除了自由度更高,可以自行引入中间件之外,更重要的是使用了 ES6 + async,从而避免了回调地狱 不过也是因 ...
- Python day 6(3) Python 函数式编程1
一:函数式编程概念 函数是Python内建支持的一种封装,我们通过把大段代码拆成函数,通过一层一层的函数调用,就可以把复杂任务分解成简单的任务,这种分解可以称之为面向过程的程序设计.函数就是面向过程的 ...
- angular4——安装
本文同样适用于NG4,最近开始学ng2了,前端小白一枚啊,做过安卓开发,做过java写的服务器啊,热爱前端啊,所以就开坑了,入坑之前建议先学下es6哦,学完后看下typescript哦,正所谓,前面基 ...
- [js高手之路] vue系列教程 - 事件专题(4)
本文主要讲解事件冒泡,事件绑定的简写,事件默认行为,按键码等一系列与事件相关的知识. 一.事件绑定的简写,@事件类型. 之前我的[js高手之路] vue系列教程 - vue的事件绑定与方法(2) 用 ...
- Win10 MySQL-python
在Windows 下调试 Python 还是挺麻烦的.通过PyCharm 来安装个MySQL-python 的库都搞了大半天.分别尝试 1.2.3,1.2.4和1.2.5都有不同的错误.需要解决的问题 ...
- Mongodb百亿级数据添加,修改,删除,查询等性能测试【四】
集群的结构,大家可以查看我的另一遍文章,Mongodb的三种集群 在最后一种集群中,介绍到. 目前使用的数据就是最后一个测试集群,留下的数据. 简单介绍一下,四个分片的配置 192.168.99.6 ...
- 转JS--通过按钮直接把input或者textarea里的值复制到粘贴板里
document.activeElement属性为HTML 5中新增的document对象的一个属性,该属性用于返回光标所在元素.当光标未落在页面中任何元素内时,属性值返回body元素. setSel ...
- 学习总结:gcc/g++ 编译与链接
gcc/g++ 编译与链接 编译与链接的过程可以分解为四个步骤:预处理.编译.汇编.链接 预处理:源代码文件和相关的头文件,被预处理器cpp预处理成一个后缀为 .i 的文件(选项:-E) 编译:把预处 ...
- 【ASP.NET MVC系列】数据验证和注解
[01]浅谈Google Chrome浏览器(理论篇) [02]浅谈Google Chrome浏览器(操作篇)(上) [03]浅谈Google Chrome浏览器(操作篇)(下) [04]浅谈ASP. ...
- 数据挖掘概念与技术15--为快速高维OLAP预计算壳片段
1. 论数据立方体预计算的多种策略的优弊 (1)计算完全立方体:需要耗费大量的存储空间和不切实际的计算时间. (2)计算冰山立方体:优于计算完全立方体,但在某种情况下,依然需要大量的存储空间和计算时间 ...