msyql 索引

索引设计原则

  • 索引并非越多越好
  • 数据量不多不需要建索引
  • 列中的值变化不多不需要建索引
  • 经常排序和分组的列需要建立索引
  • 唯一性约束对应使用唯一性索引


索引创建

普通索引

create table if not exists `user`
(
`id` int,
`name` char(10),
index `index_id`(`id`)
)engine=myisam charset=utf8;

唯一索引

create table if not exists `user`
(
`id` int,
`name` char(10),
unique index `unique_index_id`(`id`)
)engine=myisam charset=utf8;

单列索引

create table if not exists `user`
(
`id` int,
`name` char(10),
index `index_name`(`name`(5))#这里数字是索引的长度的意思
)engine=myisam charset=utf8;

索引长度

对于CHAR和VARCHAR列,只用一列的一部分就可创建索引。创建索引时,使用col_name(length)语法,对前缀编制索引。前缀包括每列值的前length个字符。BLOB和TEXT列也可以编制索引,但是必须给出前缀长度。

此处展示的语句用于创建一个索引,索引使用列名称的前10个字符。
CREATE INDEX part_of_name ON customer (name(10));

因为多数名称的前10个字符通常不同,所以此索引不会比使用列的全名创建的索引速度慢很多。另外,使用列的一部分创建索引可以使索引文件大大减小,从而节省了大量的磁盘空间,有可能提高INSERT操作的速度。

组合索引

create table if not exists `user`
(
`id` int,
`name` char(10),
index `multiple_index`(`id`,`name`)
)engine=myisam charset=utf8;

组合索引注意点

经常使用MySQL组合索引,也经常发现,其实匹配程度并不高,尤其是条件组合非常多的时候。
其实使用组合索引有这些注意点的:

比如这个索引 key(last_name, first_name, dob)
如果想使用索引,你必须保证按索引的最左边前缀(leftmost prefix of the index)来进行查询。
(1)匹配全值(Match the full value):对索引中的所有列都指定具体的值。
即所有条件都是等于,并且全部匹配

(2)匹配最左前缀(Match a leftmost prefix):仅仅使用索引中的第1列。
即索引中的最左边的用等于条件。

(3)匹配列前缀(Match a column prefix):这仅仅使用索引中的第1列。
即’X%’

(4)匹配值的范围查询(Match a range of values):仅仅使用索引中第1列。
即第一列 可以用大于 小于 X>0 and X<1

(5)匹配部分精确而其它部分进行范围匹配(Match one part exactly and match a range on another part):可以利用索引查找last name为Allen,而first name以字母K开始的人。
即,第一列 精确匹配,后面一列 范围匹配

(6)仅对索引进行查询(Index-only queries):如果查询的列都位于索引中,则不需要读取元组的值。
由于B-树中的节点都是顺序存储的,所以可以利用索引进行查找(找某些值),也可以对查询结果进行ORDER BY。

当然,使用B-tree索引有以下一些限制:
(1) 查询必须从索引的最左边的列开始。关于这点已经提了很多遍了。例如你不能利用索引查找在某一天出生的人。
(2) 不能跳过某一索引列。例如,你不能利用索引查找last name为Smith且出生于某一天的人。
(3) 存储引擎不能使用索引中范围条件右边的列。例如,如果你的查询语句为WHERE last_name=”Smith” AND first_name LIKE ‘J%’ AND dob=’1976-12-23′,则该查询只会使用索引中的前两列,因为LIKE是范围查询。

总结出来就是,使用了组合索引以后,你必须要从左到右依次精确匹配索引,能匹配多少匹配多少,直到最后一个可以匹配范围索引,只要用了某列范围索引,后面的列的索引就无效了。。所以组合索引虽好,但必须要用巧。条件并不能随便给的。

全文索引

create table if not exists `user`
(
`id` int,
`name` char(10),
fulltext index `full_index`(`name`)
)engine=myisam charset=utf8;

使用 alter 命令添加,和上面的在建表语句里面添加索引的格式是一致的

alter table `user` add index `index_id`(`id`);#添加索引

使用 create 命令添加

create index `index_name` on `user`(`name`);


索引删除

alter table `user` drop index `index_id`;#删除索引
drop index `index_name` on `user`;
for ((i=1;i<=1000000;i++));do `mysql -uroot -p123456 test -e "insert into test values ($i,floor($i + rand()*$i),md5($i))"`;done

标签: mysql, mysql索引

添加新评论