数据库索引
数据库的索引原理都是一样,这里我举的例子的索引指的是mysql的
@[toc]
概述:
- 大家都知道,索引就像是书的目录一样,通过目录查找想要的内容,当然会加快速度了,虽然这个比喻不太恰当,因为数据库要比书的原理复杂的多
- 索引分为聚集索引与非聚集索引,他们的应用范围不一样,下面我就跟大家简述下索引的原理与分类
原理:
数据库的索引其实是创建一个B +Tree ,就好比与创建了一个二叉树,那么通过二叉树查找一个百万级的数据的时候会比普通按照顺序查找要快得多(可以通过查相应节点然后知道查询结果在当前节点的左子树部分还是右子树部分,进而加快了速度),虽然二叉树与B+Tree树的结构并不相同。大家都知道,一个网站的访问速度,最主要的一个地方就是数据库的访问速度,也就是存取速度。而数据库的存取大部分时间都浪费在了对磁盘存取的IO处理上,redis为什么这么快,就是因为它完全是内存的IO,并不涉及到对磁盘的IO存取(rdb/aof持久化操作除外)所以一个关系数据库要想存取的速度变快,就只有减少对磁盘的IO操作,怎么样能减少磁盘的IO操作呢,B+Tree树结构就是一个很好的减少对磁盘IO处理的方法。
建立索引方法:
1、建立普通索引:
01 –直接创建索引
02 CREATE INDEX index_name ON table(column(length))
03 –修改表结构的方式添加索引
04 ALTER TABLE table_name ADD INDEX index_name ON (column(length))
05 –创建表的时候同时创建索引
06 CREATE TABLE `table` (
07 `id` int(11) NOT NULL AUTO_INCREMENT ,
08 `title` char(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ,
09 `content` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL ,
10 `time` int(10) NULL DEFAULT NULL ,
11 PRIMARY KEY (`id`),
12 INDEX index_name (title(length))
13 )
14 –删除索引
15 DROP INDEX index_name ON table
2、创建唯一索引:
01 –创建唯一索引
02 CREATE UNIQUE INDEX indexName ON table(column(length))
03 –修改表结构
04 ALTER TABLE table_name ADD UNIQUE indexName ON (column(length))
05 –创建表的时候直接指定
06 CREATE TABLE `table` (
07 `id` int(11) NOT NULL AUTO_INCREMENT ,
08 `title` char(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ,
09 `content` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL ,
10 `time` int(10) NULL DEFAULT NULL ,
11 PRIMARY KEY (`id`),
12 UNIQUE indexName (title(length))
13 );
3. 全文索引(FULLTEXT)
如果对大量数据进行全文索引,非常消耗磁盘空间
01 –创建表的适合添加全文索引
02 CREATE TABLE `table` (
03 `id` int(11) NOT NULL AUTO_INCREMENT ,
04 `title` char(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ,
05 `content` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL ,
06 `time` int(10) NULL DEFAULT NULL ,
07 PRIMARY KEY (`id`),
08 FULLTEXT (content)
09 );
10 –修改表结构添加全文索引
11 ALTER TABLE article ADD FULLTEXT index_content(content)
12 –直接创建索引
13 CREATE FULLTEXT INDEX index_content ON article(content)
4、 组合索引(最左前缀)
>ALTER TABLE article ADD INDEX index_time_time (title(50),time(10));
1 –使用到上面的索引
2 SELECT * FROM article WHREE title='测试' AND time=1234567890;
3 SELECT * FROM article WHREE utitle='测试';
4 –不使用上面的索引
5 SELECT * FROM article WHREE time=1234567890;
建立索引不怎么费时间,顶多会占用大量磁盘空间,在实际情况中磁盘空间是绝对够用的,那么索引带来的弊端是什么呢?
<font size ="4" color="#9370DB"><b>首先,建立索引是用来查询的,也就是说,只有需要大量的反复的查询索引,才有建立索引的必要,并且建立好了索引,会带来插入数据时会比没有建立索引之前要慢一点的代价。尤其是全文索引: 在将大量数据插入后建立索引会比先建立索引然后再插入数据所用的时间要短得多。</font>
使用索引的注意事项:
1、注意数量级
当查询返回的结果特别多的情况下,比如查询性别,性别之分男女(第三种第四种甚至第五种情况这里先不做讨论),这种情况下返回的数量会是将近一半的数量,这时候建立这个字段的索引有没有必要,甚至建立索引比不建立索引时查询的速度更慢。
2、左前缀原则
当建立联合(组合)索引时,遵循最左前缀原则,也就是建立索引时的字段从左到右排列,
比如id,name,age 三个字段
当select * from table where id=1 and name="东风削铁虫"and age=21 时是会走联合索引的。
这样:
select * from table where id=1 and name="东风削铁虫" 也是走索引的。
但是:
select * from table where id=1 and age=21 是不走索引的。
select * from table where and name="东风削铁虫"and age=21 这样也是不走索引的
3、当建立联合索引时(还用上面的例子),双范围查询是不走索引滴:
select * from table where id>12 and name="东风削铁虫"and age<18 这样就是 18禁 哈哈,多少也要禁的
这样查询就没事:
select * from table where id=12 and name="东风削铁虫"and age<18
4、当使用索引时,模糊查询的 “ % ”要写到后面而不能写到前面:
select * from table where name like "东风削%"