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

索引用于快速找出在某个列中有一特定值的行。不使用索引,MySQL必须从第1条记录开始而后读完整个表直到找出相关的行,还须要考虑每次读入数据页的IO开销。而若是采起索引,则能够根据索引指向的页以及记录在页中的位置,迅速地读取目标页进而获取目标记录。mysql

大多数状况下都(默认)采用B树来构建索引。只是空间列类型的索引使用R-树,而且MEMORY表还支持hash索引。B树是平衡多叉树,每一个节点存放多少个值取决于值所占的空间,这与每一张数据页存放多少条记录与记录信息量有关同理。节点中的值是以非降序进行排列的,节点中的值老是小于等于指向它的结点中的值。sql

MySQL使用B树构造索引的状况下,是由叶子指向具体的页和记录的。而且一个叶子有一个指针指向下一个叶子。函数

 

使用索引须要注意:优化

⑴只对WHERE和ORDER BY须要查询的字段设置索引,避免无心义的硬盘开销;google

⑵组合索引支持前缀索引;spa

⑶更新表的时候,如增删记录,MySQL会自动更新索引,保持树的平衡;所以更多的索引意味着更多的维护成本设计

 索引的字段类型问题指针

  • text类型,也可建索引(需指定长度)
  • myisam存储引擎索引键长度综合不能超过1000字节
  • 用来筛选的值尽可能保持和索引列一样的数据类型

索引分四类:htm

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



mysql 复合索引,联合索引 - flyflying1987 - ly
索引原则

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注入

相关文章
相关标签/搜索