:最左前缀原则中where字句有or出现还是会遍历全表

(1) 其实where条件的顺序不影响使用索引,比如三个字段添加联合索引t_user表联合索引(name, mobile, create_date)

select * from t_user where mobile = ‘13256767876‘ and create_date= ‘2017-07-31‘ and name = ‘corner‘;

理论上索引对顺序是敏感的,但是由于MySQL的查询优化器会自动调整where子句的条件顺序以使用适合的索引,所以这样也是可以用到索引的

(2)查询条件没有指定索引第一列

如果where条件中没有name条件,只有另外两个无论顺序是什么都是无法用到索引的,如果where条件只有name,status而没有mobile这时候只能用到一列索引,status这一列的索引是用不到的

(3)范围查询

范围列可以用到索引(必须是最左前缀),但是范围列后面的列无法用到索引。同时,索引最多用于一个范围列,因此如果查询条件中有两个范围列则无法全用到索引

表t_title联合索引(emp_no,title,from_date)

EXPLAIN SELECT * FROMemployees.titles

WHERE emp_no < ‘10010‘

AND title=‘Senior Engineer‘

AND from_date BETWEEN ‘1986-01-01‘ AND ‘1986-12-31‘;

+----+-------------+--------+-------+---------------+---------+---------+------+------+-------------+| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |

+----+-------------+--------+-------+---------------+---------+---------+------+------+-------------+| 1 | SIMPLE | titles | range | PRIMARY | PRIMARY | 4 | NULL | 16| Using where |

+----+-------------+--------+-------+---------------+---------+---------+------+------+-------------+

只能用到第一列索引,这里特别要说明MySQL一个有意思的地方,那就是仅用explain可能无法区分范围索引和多值匹配,因为在type中这两者都显示为range。同时,用了“between”并不意味着就是范围查询,例如下面的查询:

全部索引都用到了

EXPLAIN SELECT * FROMemployees.titles

WHERE emp_no BETWEEN ‘10001‘ AND ‘10010‘

AND title=‘Senior Engineer‘

AND from_date BETWEEN ‘1986-01-01‘ AND ‘1986-12-31‘;

+----+-------------+--------+-------+---------------+---------+---------+------+------+-------------+| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |

+----+-------------+--------+-------+---------------+---------+---------+------+------+-------------+| 1 | SIMPLE | titles | range | PRIMARY | PRIMARY | 59 | NULL | 16| Using where |

+----+-------------+--------+-------+---------------+---------+---------+------+------+-------------+

(4)查询条件中含有函数或表达式

如果查询条件中含有函数或表达式,则MySQL不会为这列使用索引

like如果通配符%不出现在开头,则可以用到索引,但根据具体情况不同可能只会用其中一个前缀

EXPLAIN SELECT * FROM employees.titles WHERE emp_no=‘10001‘ AND title LIKE ‘Senior%‘;

+----+-------------+--------+-------+---------------+---------+---------+------+------+-------------+| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |

+----+-------------+--------+-------+---------------+---------+---------+------+------+-------------+| 1 | SIMPLE | titles | range | PRIMARY | PRIMARY | 56 | NULL | 1| Using where |

+----+-------------+--------+-------+---------------+---------+---------+------+------+-------------+

4.索引选择性与前缀索引

(1)什么情况下判断字段是否应该建立索引,今天刚看到这个"选择性"的概念,除了表数据很少的情况不用建索引因为索引文件本身要消耗存储空间会加重数据库操作的负担,另外一种情况就是索引的选择性比较低:

所谓索引的选择性(Selectivity),是指不重复的索引值(也叫基数,Cardinality)与表记录数(#T)的比值:Index Selectivity = Cardinality / #T

显然选择性的取值范围为(0, 1],选择性越高的索引价值越大,这是由B+Tree的性质决定的。

这个问题就像是面试时提问我的一个问题:性别列适不适合建立索引?(答案是否定的)

例如,上文用到的employees.titles表,如果title字段经常被单独查询,是否需要建索引,我们看一下它的选择性:

SELECT count(DISTINCT(title))/count(*) AS Selectivity FROMemployees.titles;

+-------------+| Selectivity |

+-------------+| 0.0000|

+-------------+

title的选择性不足0.0001(精确值为0.00001579),所以实在没有什么必要为其单独建索引。

(2)有一种与索引选择性有关的索引优化策略叫做前缀索引,就是用列的前缀代替整个列作为索引key,当前缀长度合适时,可以做到既使得前缀索引的选择性接近全列索引,同时因为索引key变短而减少了索引文件的大小和维护开销。下面以employees.employees表为例介绍前缀索引的选择和使用。

从图12可以看到employees表只有一个索引,那么如果我们想按名字搜索一个人,就只能全表扫描了:

EXPLAIN SELECT * FROM employees.employees WHERE first_name=‘Eric‘ AND last_name=‘Anido‘;

+----+-------------+-----------+------+---------------+------+---------+------+--------+-------------+| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |

+----+-------------+-----------+------+---------------+------+---------+------+--------+-------------+| 1 | SIMPLE | employees | ALL | NULL | NULL | NULL | NULL | 300024| Using where |

+----+-------------+-----------+------+---------------+------+---------+------+--------+-------------+

如果频繁按名字搜索员工,这样显然效率很低,因此我们可以考虑建索引。有两种选择,建或,看下两个索引的选择性:

SELECT count(DISTINCT(first_name))/count(*) AS Selectivity FROMemployees.employees;

+-------------+| Selectivity |

+-------------+| 0.0042|

+-------------+

SELECT count(DISTINCT(concat(first_name, last_name)))/count(*) AS Selectivity FROMemployees.employees;

+-------------+| Selectivity |

+-------------+| 0.9313|

+-------------+

显然选择性太低,选择性很好,但是first_name和last_name加起来长度为30,有没有兼顾长度和选择性的办法?可以考虑用first_name和last_name的前几个字符建立索引,例如,看看其选择性:

SELECT count(DISTINCT(concat(first_name, left(last_name, 3))))/count(*) AS Selectivity FROMemployees.employees;

+-------------+| Selectivity |

+-------------+| 0.7879|

+-------------+

选择性还不错,但离0.9313还是有点距离,那么把last_name前缀加到4:

SELECT count(DISTINCT(concat(first_name, left(last_name, 4))))/count(*) AS Selectivity FROMemployees.employees;

+-------------+| Selectivity |

+-------------+| 0.9007|

+-------------+

这时选择性已经很理想了,而这个索引的长度只有18,比短了接近一半,我们把这个前缀索引 建上:

ALTER TABLEemployees.employees

ADD INDEX first_name_last_name4 (first_name, last_name(4));

此时再执行一遍按名字查询,比较分析一下与建索引前的结果:

SHOW PROFILES;

+----------+------------+---------------------------------------------------------------------------------+| Query_ID | Duration | Query |

+----------+------------+---------------------------------------------------------------------------------+| 87 | 0.11941700 | SELECT * FROM employees.employees WHERE first_name=‘Eric‘ AND last_name=‘Anido‘|

| 90 | 0.00092400 | SELECT * FROM employees.employees WHERE first_name=‘Eric‘ AND last_name=‘Anido‘|

+----------+------------+---------------------------------------------------------------------------------+

mysql索引以及优化

标签:第一个   指定   意图   查询条件   sim   简单   介绍   tween   存在

本条技术文章来源于互联网,如果无意侵犯您的权益请点击此处反馈版权投诉

本文系统来源:http://www.cnblogs.com/mantianxing/p/7270052.html

手机号 mysql 索引_mysql索引以及优化相关推荐

  1. 手机号mysql索引_Mysql索引总结

    索引原理​ MySQL官方对索引的定义为:索引(Index)是帮助MySQL高效获取数据的数据结构.提取句子主干,就可以得到索引的本质:索引是数据结构. ​ 数据库查询是数据库的最主要功能之一.我们都 ...

  2. mysql 大量数据 更改索引_Mysql索引数据结构详解与索引优化

    本篇文章主要学习了MySQL的索引的数据结构的认识,做一个大概的了解即可. 一.索引 在关系数据库中,索引是一种单独的.物理的对数据库表中一列或多列的值进行排序的一种存储数据结构,它是某个表中一列或若 ...

  3. mysql字段简索引_Mysql索引优化攻略(全)

    所谓索引就是为特定的mysql字段进行一些特定的算法排序,比如二叉树的算法和哈希算法,哈希算法是通过建立特征值,然后根据特征值来快速查找.而用的最多,并且是mysql默认的就是二叉树算法 BTREE, ...

  4. mysql 排序字段是否需要建索引_MySQL索引详解(优缺点,何时需要/不需要创建索引,索引及sql语句的优化)...

    一.什么是索引? 索引是对数据库表中的一列或多列值进行排序的一种结构,使用索引可以快速访问数据库表中的特定信息. 二.索引的作用? 索引相当于图书上的目录,可以根据目录上的页码快速找到所需的内容,提高 ...

  5. mysql 更新索引_MySQL索引优化

    MySQL支持的索引类型 B-tree索引的特点 1.B-tree索引以B+树的结构存储数据 2.B-tree索引能够加快数据的查询速度 3.B-tree索引更适合进行行范围查找 B-tree结构图 ...

  6. mysql or 创建索引_Mysql索引优化

    1.单表索引优化 单表索引优化分析 创建表 建表 SQL CREATE TABLE IF NOT EXISTS article( id INT(10) UNSIGNED NOT NULL PRIMAR ...

  7. mysql 前索引_MySQL查询性能优化前,必须先掌握MySQL索引理论

    数据库索引在平时的工作是必备的,怎么建好索引,怎么使用索引,可以提高数据的查询效率.而且在面试过程,数据库的索引也是必问的知识点,比如: 索引底层结构选型,那为什么选择B+树? 不同存储引擎的索引的体 ...

  8. mysql locate索引_MYSQL索引优化

    1.查看sql的执行频率 MySQL 客户端连接成功后,通过 show [session|global] status 命令可以提供服务器状态信息.show [session|global] stat ...

  9. mysql locate不走索引_MySQL 索引——定位并优化慢 SQL

    定位并优化慢查询SQL.png 为什么要学习定位并优化慢查询 SQL 日常开发中,在数据量比较小的表中,SQL 的执行效率可能没什么问题,但是随着表数据量的增加,慢 SQL 可能就会慢慢浮现,因此学习 ...

最新文章

  1. mvc core2.1 Identity.EntityFramework Core 注册 (二)
  2. Data-Mediator专题之属性回调
  3. 读“NoSQL注入的分析和缓解”之摘录
  4. [Unity3d]多个摄像机叠加效果
  5. python 公开课_python公开课视频(11~20)
  6. 2021曾都二中高考成绩查询入口,2021高考-随州设4个考区11个考点·
  7. XAF框架简介-C#语言
  8. DS1302时钟基础使用(含代码)
  9. js 浏览器永久保存数据:localStorage
  10. html5 鼠标双击,鼠标双击或触摸双击事件检测jQuery插件
  11. 米的换算单位和公式_小学数学单位换算公式大全.doc
  12. 微交易平台搭建开发-盘内实时K线对接
  13. h5 vr效果_全景展示h5,深度解读如何在H5中完美融入VR技术
  14. 缓冲区(1):为什么会有缓冲区(缓存)?
  15. 第三个计算机时代为,计算机三个时代的各自特点?
  16. 玩转代码|异步加载 CSS 的最简单方法
  17. javascript中mouseenter与mouseover的异同
  18. 国外的个性化定制站点
  19. C语言课程设计:图书信息管理系统
  20. 零基础学平面设计还学美工设计比较有前途?

热门文章

  1. 计算机网络典型的通信协议有,常用的通信网络协议有哪几种
  2. 在wget中指定代理服务器
  3. 下载网页blob视频
  4. 复杂系统理论解释了Covid为何粉碎世界
  5. !include: could not find: “nsProcessW.nsh“
  6. 全国计算机考试比省级的难吗,国考和省考考题的区别,难度差异很大吗?
  7. 实现一个简单的图片轮播效果
  8. 用友U8案例实验应收管理后台配置
  9. ES6_1.块级作用域绑定_临时死区TDZ
  10. 百度违规屏蔽关键词工具