索引用于快速找出在某个列中有一特定值的行。不使用索引,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还是比人脑厉害太多

转载自:http://www.cnblogs.com/DaBing0806/p/4876228.html

mysql 理解索引,添加索引,使用索引(哪些情况会导致索引失效)的更多相关文章

  1. mybatis的sql语句导致索引失效,使得查询超时

    mybaitis书写sql需要特别注意where条件中的语句,否则将会导致索引失效,使得查询总是超时.如下语句会出现导致索引失效的情况: with test1 as (select count(C_F ...

  2. 【转】MySQL理解索引、添加索引的原则

    索引用于快速找出在某个列中有一特定值的行.不使用索引,MySQL必须从第1条记录开始然后读完整个表直到找出相关的行,还需要考虑每次读入数据页的IO开销.而如果采取索引,则可以根据索引指向的页以及记录在 ...

  3. MySQL理解索引、添加索引的原则

    索引用于快速找出在某个列中有一特定值的行.不使用索引,MySQL必须从第1条记录开始然后读完整个表直到找出相关的行,还需要考虑每次读入数据页的IO开销.而如果采取索引,则可以根据索引指向的页以及记录在 ...

  4. mysql 分析5语句的优化--索引添加删除

    查看表的索引  show create table 表名; show index from 表名; show keys from表名; 添加索引 alter table 表名  add index 索 ...

  5. MySQL中IS NULL、IS NOT NULL、!=不能用索引?胡扯!

    转:https://mp.weixin.qq.com/s/CEJFsDBizdl0SvugGX7UmQ 不知道从什么时候开始,网上流传着这么一个说法: MySQL的WHERE子句中包含 IS NULL ...

  6. MySQL索引背后的之使用策略及优化(高性能索引策略)

    为了讨论索引策略,需要一个数据量不算小的数据库作为示例.本文选用MySQL官方文档中提供的示例数据库之一:employees.这个数据库关系复杂度适中,且数据量较大.下图是这个数据库的E-R关系图(引 ...

  7. 数据库表设计时一对一关系存在的必要性 数据库一对一、一对多、多对多设计 面试逻辑题3.31 sql server 查询某个表被哪些存储过程调用 DataTable根据字段去重 .Net Core Cors中间件解析 分析MySQL中哪些情况下数据库索引会失效

    数据库表设计时一对一关系存在的必要性 2017年07月24日 10:01:07 阅读数:694 在表设计过程中,我无意中觉得一对一关系觉得好没道理,直接放到一张表中不就可以了吗?真是说,网上信息什么都 ...

  8. Mysql高手系列 - 第24篇:如何正确的使用索引?【高手进阶】

    Mysql系列的目标是:通过这个系列从入门到全面掌握一个高级开发所需要的全部技能. 欢迎大家加我微信itsoku一起交流java.算法.数据库相关技术. 这是Mysql系列第24篇. 学习索引,主要是 ...

  9. 012-MySQL 索引添加以及优化说明

    一.索引概述 数据库的索引可以加快查询速度,原因是索引使用特定的数据结构(B-Tree)对特定的列额外组织存放,加快存储引擎(索引是存储引擎实现)查找记录的速度. 如果查询语句使用索引(通常是wher ...

随机推荐

  1. PyQt: “AttributeError: 'Form' object has no attribute 'exec_'” when opening second window

    # -*- coding: utf-8 -*- import sys from PyQt5.QtWidgets import QApplication , QMainWindow from PyQt5 ...

  2. vue-one_demo_music

    简单的音乐盒子 利用计算属性(监听数据),解决上一首,下一首,点击切换 <!DOCTYPE html> <html lang="en"> <head& ...

  3. U-Boot 不能识别FAT32 SD分区

    /********************************************************************* * U-Boot 不能识别FAT32 SD分区 * 说明: ...

  4. from sklearn.datasets import make_classification创建分类数据集

    make_classification创建用于分类的数据集,官方文档 例子: ### 创建模型 def create_model(): # 生成数据 from sklearn.datasets imp ...

  5. Git 过滤文件,控制上传

    在Git的版本控制中,可能有些文件是不需要加入控制的,那我们在提交代码时就需要忽略这些文件,下面讲讲应该怎么给Git配置一些忽略规则. 有三种方法可以忽略掉这些文件,这三种方法都能达到目的,只不过适用 ...

  6. 类中的__slots__方法与__dict__方法相排斥

    类的 __slots__ 列表 作用: 限定一个类创建的实例只能有固定的属性(实例变量) 不允许对象添加列表以外的属性(实例变量) 防止用户因错写属性的名称而发生程序错误 说明: 1. __slots ...

  7. C的文件操作函数

    fgetc(FILE *)意为从文件指针stream指向的文件中读取一个字符,读取一个字节后,光标位置后移一个字节fputc(char,FILE*)将字符ch写到文件指针fp所指向的文件的当前写指针的 ...

  8. 每天一个linux命令(性能、优化):【转载】top命令

    top命令是Linux下常用的性能分析工具,能够实时显示系统中各个进程的资源占用状况,类似于Windows的任务管理器.下面详细介绍它的使用方法.top是一个动态显示过程,即可以通过用户按键来不断刷新 ...

  9. scrapy爬取验证码登录网页

    scrapy 验证码登录程序, https://accounts.douban.com/login # -*- coding: utf-8 -*- import scrapy import urlli ...

  10. java 类加载器体系结构