数据库优化-索引

一、索引

1、概念

  索引:一种数据结构或存储结构;数据库系统除数据外,还维护着满足特定查找算法的数据结构,这些数据结构以某种方式引用(指向)数据用以实现高级查找算法;对数据库表中一列或多列的值进行排序的一种结构;

  所以,使用索引的代价:一是增加了数据库的存储空间,二是在插入和修改数据时要花费较多的时间(因为索引也要随之变动);

  三种索引:唯一索引、主键索引和聚集索引

  唯一索引:不允许表中任意两行在相同索引列具有相同的值;

  主键索引:数据库表经常有一列或列组合,其值唯一标识表中的每一行,这一列成为主键,定义主键将自动创建主键索引;主键索引是唯一索引的特殊情况;

  聚集索引:数据库表行中数据的物理顺序与键值的逻辑(索引)顺序相同;一个表中的数据的物理顺序只有一种,所以聚集索引只有一种;

  优点:提高查询检索的速度;

  缺点:维护索引费事费空间;

2、原理

  局部性原理:当一个数据被用到时,其附近的数据也通常会马上被使用。程序运行期间所需要的数据通常比较集中。

  磁盘预读:磁盘比内存速度慢,加之机械运动耗时,磁盘I/O效率低;磁盘I/O往往不是严格按需读取,而是每次都会预读,即使只需要一个字节,磁盘也会从这个位置开始,顺序向后读取一定长度的数据放入内存,预读的长度一般为页(page)的整倍数;

  索引的实现通常使用B树及其变种B+树;

3、实现

  创建索引:ALTER 、CREATE 

  ALTER TABLE用来创建普通索引、UNIQUE索引或PRIMARY KEY索引。
  ALTER TABLE table_name ADD INDEX index_name (column_list)
  ALTER TABLE table_name ADD UNIQUE (column_list)
  ALTER TABLE table_name ADD PRIMARY KEY (column_list)
 
  CREATE INDEX可对表增加普通索引或UNIQUE索引。
  CREATE INDEX index_name ON table_name (column_list)
  CREATE UNIQUE INDEX index_name ON table_name (column_list)
  其中table_name是要增加索引的表名,column_list指出对哪些列进行索引,多列时各列之间用逗号分隔。索引名index_name可选,缺省时,MySQL将根据第一个索引列赋一个名称。
  另外,ALTER TABLE允许在单个语句中更改多个表,因此可以在同时创建多个索引,不能用CREATE INDEX语句创建PRIMARY KEY索引。
  
  删除索引:ALTER 、DROP 
  ALTER TABLE table_name DROP INDEX index_name
  ALTER TABLE table_name DROP PRIMARY KEY
  DROP INDEX index_name ON talbe_name

4、使用

  场景:数据表数据较大;索引列尽量不会出现重复数据;索引列经常会用来进行查询;索引列的单个数据不会超级小或者超级大;

  语句一:selectnamefrom商品表。不会用到索引,因为没有where语句。

  语句二:select*from商品表wherename=‘Java书’,会用到索引,如果项目里经常用到name来查询,且商品表的数据量很大,而name值的重复率又不高,那么建议建索引。

  语句三:select*from商品表wherenamelike‘Java%’这是个模糊查询,会用到索引,请大家记住,用like进行模糊查询时,如果第一个就是模糊的匹配符,比如wherenamelike‘%java’,那么在查询时不会走索引。在其他情况下,不论用了多少个%,也不论%的位置,只要不出现在第一个位置,那么都能用到索引。

学生成绩表里有两个字段:姓名和成绩。现在对成绩这个整数类型的字段建索引。

  第一种情况,当数字型字段遇到非等值操作符时,无法用到索引。比如:

selectnamefrom学生成绩表where成绩>95,一旦出现大于符号,就不能用到索引,为了用到索引,我们应该改一下SQL语句里的where从句:where成绩in(96,97,98,99,100)

  第二种情况,如果对索引字段进行了某种左值操作,那么无法用到索引。

能用到索引的写法:selectnamefrom学生成绩表where成绩=60

不能用到索引的写法:selectnamefrom学生成绩表where成绩+40=100

  第三种情况,如果对索引字段进行了函数操作,那么无法用到索引。

比如SQL语句:select*from商品表wheresubstr(name)=‘J’,我们希望查询商品名首字母是J的记录,可一旦针对name使用函数,即使name字段上有索引,也无法用到。

  

posted on 2018-01-18 16:26  奇天异下  阅读(258)  评论(0编辑  收藏  举报

导航