【转】MySQL理解索引、添加索引的原则
索引用于快速找出在某个列中有一特定值的行。不使用索引,MySQL必须从第1条记录开始然后读完整个表直到找出相关的行,还需要考虑每次读入数据页的IO开销。而如果采取索引,则可以根据索引指向的页以及记录在页中的位置,迅速地读取目标页进而获取目标记录。
大多数情况下都(默认)采用B树来构建索引。只是空间列类型的索引使用R-树,并且MEMORY表还支持hash索引。B树是平衡多叉树,每个节点存放多少个值取决于值所占的空间,这与每一张数据页存放多少条记录与记录信息量有关同理。节点中的值是以非降序进行排列的,节点中的值总是小于等于指向它的结点中的值。
MySQL使用B树构造索引的情况下,是由叶子指向具体的页和记录的。并且一个叶子有一个指针指向下一个叶子。
使用索引需要注意:
⑴只对WHERE和ORDER BY需要查询的字段设置索引,避免无意义的硬盘开销;
⑵组合索引支持前缀索引;
⑶更新表的时候,如增删记录,MySQL会自动更新索引,保持树的平衡;因此更多的索引意味着更多的维护成本
索引的字段类型问题
- text类型,也可建索引(需指定长度)
- myisam存储引擎索引键长度综合不能超过1000字节
- 用来筛选的值尽量保持和索引列同样的数据类型
索引分四类:
index ----普通的索引,数据可以重复
fulltext----全文索引,用来对大表的文本域(char,varchar,text)进行索引。语法和普通索引一样。
unique ----唯一索引,唯一索引,要求所有记录都唯一
primary key ----主键索引,也就是在唯一索引的基础上相应的列必须为主键
like 不能用索引?
- 尽量减少like,但不是绝对不可用,”xxxx%” 是可以用到索引的,
想象一下,你在看一本成语词典,目录是按成语拼音顺序建立,查询需求是,你想找以 “一”字开头的成语(”一%“),和你想找包含一字的成语(“%一%”)
- 除了like,以下操作符也可用到索引:
<,<=,=,>,>=,BETWEEN,IN
<>,not in ,!=则不行
原则
1,单表数据太少,索引反而会影响速度;更新非常频繁的数据不适宜建索引
2,where后的条件,order by ,group by 等这样过滤时,后面的字段最好加上索引。根据实际情况,选择PRIMARY KEY、UNIQUE、INDEX等索引,但是不是越多越好,要适度
3,联合查询,子查询等多表操作时关连字段要加索引
ps:数据量特别大的时候,最好不要用联合查询,即使你做了索引
多列查询该如何建索引?
一次查询只能用到一个索引,所以 首先枪毙 a,b各建索引方案
a还是b? 谁的区分度更高(同值的最少),建谁!
当然,联合索引也是个不错的方案,ab,还是ba,则同上,区分度高者,在前
联合索引的问题?
where a = “xxx” 可以使用 AB 联合索引
where b = “xxx” 则不可 (再想象一下,这是书的目录?)
所以,大多数情况下,有AB索引了,就可以不用在去建一个A索引了
详解:
联合索引又叫复合索引。对于复合索引:Mysql从左到右的使用索引中的字段,一个查询可以只使用索引中的一部份,但只能是最左侧部分。例如索引是key index (a,b,c). 可以支持a | a,b| a,b,c 3种组合进行查找,但不支持 b,c进行查找 .当最左侧字段是常量引用时,索引就十分有效。
两个或更多个列上的索引被称作复合索引。
利用索引中的附加列,您可以缩小搜索的范围,但使用一个具有两列的索引 不同于使用两个单独的索引。复合索引的结构与电话簿类似,人名由姓和名构成,电话簿首先按姓氏对进行排序,然后按名字对有相同姓氏的人进行排序。如果您知 道姓,电话簿将非常有用;如果您知道姓和名,电话簿则更为有用,但如果您只知道名不姓,电话簿将没有用处。
所以说创建复合索引时,应该仔细考虑列的顺序。对索引中的所有列执行搜索或仅对前几列执行搜索时,复合索引非常有用;仅对后面的任意列执行搜索时,复合索引则没有用处。
如:建立 姓名、年龄、性别的复合索引。
create table test(
a int,
b int,
c int,
KEY a(a,b,c)
);
优: select * from test where a=10 and b>50
差: select * from test where a50
优: select * from test order by a
差: select * from test order by b
差: select * from test order by c
优: select * from test where a=10 order by a
优: select * from test where a=10 order by b
差: select * from test where a=10 order by c
优: select * from test where a>10 order by a
差: select * from test where a>10 order by b
差: select * from test where a>10 order by c
优: select * from test where a=10 and b=10 order by a
优: select * from test where a=10 and b=10 order by b
优: select * from test where a=10 and b=10 order by c
优: select * from test where a=10 and b=10 order by a
优: select * from test where a=10 and b>10 order by b
差: select * from test where a=10 and b>10 order by c
1.索引越少越好
原因:主要在修改数据时,第个索引都要进行更新,降低写速度。
2.最窄的字段放在键的左边
3.避免file sort排序,临时表和表扫描.
哪些常见情况不能用索引?
- like “%xxx”
- not in , !=
- 对列进行函数运算的情况(如 where md5(password) = “xxxx”)
- WHERE index=1 OR A=10
- 存了数值的字符串类型字段(如手机号),查询时记得不要丢掉值的引号,否则无法用到该字段相关索引,反之则没关系
也即
select * from test where mobile = 13711112222;
可是无法用到mobile字段的索引的哦(如果mobile是char 或 varchar类型的话)
btw,千万不要尝试用int来存手机号(为什么?自己想!要不自己试试)
覆盖索引(Covering Indexes)拥有更高效率
索引包含了所需的全部值的话,就只select 他们,换言之,只select 需要用到的字段,如无必要,可尽量避免select *
NULL 的问题
NULL会导致索引形同虚设,所以在设计表结构时应避免NULL 的存在(用其他方式表达你想表达的NULL,比如 -1?)
如何查看索引信息,如何分析是否正确用到索引?
show index from tablename;
explain select ……;
关于explain,改天可以找个时间专门写一篇入门帖,在此之前,可以尝试 google
了解自己的系统,不要过早优化!
过早优化,一直是个非常讨厌而又时刻存在的问题,大多数时候就是因为不了解自己的系统,不知道自己系统真正的承载能力
比如:几千条数据的新闻表,每天几百几千次的正文搜索,大多数时候我们可以放心的去like,而不要又去建一套全文搜索什么的,毕竟cpu还是比人脑厉害太多
最后:永远别忘记的关键词sql注入
from:http://www.cnblogs.com/DaBing0806/p/4876228.html
【转】MySQL理解索引、添加索引的原则的更多相关文章
- mysql之数据库添加索引优化查询效率
项目中如果表中的数据过多的话,会影响查询的效率,那么我们需要想办法优化查询,通常添加索引就是我们的选择之一: 1.添加PRIMARY KEY(主键索引) mysql>ALTER TABLE `t ...
- Mysql中大表添加索引的办法
Hash索引与 Btree索引的区别http://database.51cto.com/art/201010/229525.htm Creating Indexes/Sorting on very l ...
- MySQL进阶之MySQL索引以及索引优化
本文配合B站学习视频BV1es411u7we使用效果更佳. 1. MySQL版本 主流版本:5.x版 5.0 - 5.1:早期产品的延续,升级维护 5.4 - 5.x:MySQL整合了三方公司的新存储 ...
- oracle 常用索引分析,使用原则和注意事项
本文参考: https://www.cnblogs.com/wishyouhappy/p/3681771.html https://blog.csdn.net/weivi001/article/det ...
- 添加索引:BLOB/TEXT column 'xxx' used in key specification without a key length
问题 1. 将DataFrame数据保存到mysql后,添加索引出现错误提示: BLOB/TEXT column used in key specification without a key len ...
- MySQL数据库开发的36条原则【华为云技术分享】
版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/devcloud/article/detai ...
- MySQL数据库开发的36条原则
欢迎添加华为云小助手微信(微信号:HWCloud002 或 HWCloud003),验证通过后,输入关键字"加群",加入华为云线上技术讨论群:输入关键字"最新活动&quo ...
- MySQL理解索引、添加索引的原则
索引用于快速找出在某个列中有一特定值的行.不使用索引,MySQL必须从第1条记录开始然后读完整个表直到找出相关的行,还需要考虑每次读入数据页的IO开销.而如果采取索引,则可以根据索引指向的页以及记录在 ...
- mysql 理解索引,添加索引,使用索引(哪些情况会导致索引失效)
索引用于快速找出在某个列中有一特定值的行.不使用索引,MySQL必须从第1条记录开始然后读完整个表直到找出相关的行,还需要考虑每次读入数据页的IO开销.而如果采取索引,则可以根据索引指向的页以及记录在 ...
随机推荐
- Umbraco 7 特点
Umbraco 7 features at a glance The backend is mainly built on .NET C# MVC. There are some leftovers ...
- [android] 手机卫士读取联系人
获取ContentResolver内容解析器对象,通过getContentResolver()方法 调用ContentResolver对象的query()方法,得到raw_contacts表里面的数据 ...
- [android] 手机卫士欢迎细节和主界面
splash界面的细节 ctrl + O 搜索 在去标题的时候,对话框主题被去掉了,有点丑,现在既要有新版本的对话框又不显示标题 把清单文件中activity节点的主题去掉 进入到applicatio ...
- JavaSE 异常抛光解析
异常 异常指的是程序中的不正常现象,一般异常都是由第三方数据的使用造成的.java中每种异常现象都会有一个对应的异常类.java对异常的处理方式就是终止程序.异常机制其实是为了帮助我们找到程序中的问题 ...
- Swagger2限定接口范围
前面在使用Swagger2时遇到的坑中简单介绍了Swagger的使用. 不过默认情况下,Swagger2会把项目中的所有接口都展示在列表里,特别是你用了Springboot/SpringCloud之后 ...
- deepin使用笔记-解决安装并解决gvim没有启动器的问题
我的邮箱地址:zytrenren@163.com欢迎大家交流学习纠错! 1.安装gvim #apt-get install vim-gtk3 2.创建桌面启动器 创建/usr/share/applic ...
- HTML的head标签
前端开发工具介绍: Hbuilder:可以快速的生成HTML标准文档结构,集成了很多方便的快捷键.--------------------------------------------------- ...
- sql server: 最短路径
--------------------------------------------------------------------- -- Road System 道路 ------------ ...
- BZOJ4259: 残缺的字符串(FFT 字符串匹配)
题意 题目链接 Sol 知道FFT能做字符串匹配的话这就是个裸题了吧.. 考虑把B翻转过来,如果\(\sum_{k = 0}^M (B_{i - k} - A_k)^2 * B_{i-k}*A_k = ...
- [VUE ERROR] Error in render: "TypeError: Cannot create property 'header' on boolean 'true'"
项目基于ElemnetUi进行的开发,在引入第三方扩展库 vue-element-extends 之后使用它的表格组件报了这个错 解决方案: 1. 删除项目中的 node_modules 2. 删除 ...