SQL优化之索引

举例说明:
假设有一个图书Book表,里面有字段id,name, isbn等。若是图书数量巨大的话,咱们经过isbn查询一般是比较慢的。
这里写图片描述
这里写图片描述
添加索引:
create index index_isbn ON book (isbn);web

再次执行查询:
这里写图片描述
这里写图片描述
查询时间从0.134缩短到0.001,效果仍是很明显的。数据库

接下来经过一个故事来讲明一下,索引是什么?svg

好久之前,在一个古城的的大图书馆中珍藏有成千上万本书籍,但书架上的书没有按任何顺序摆放,所以每当有人询问某本书时,图书管理员只有挨个寻找,每一次都要花费大量的时间。[这就比如数据表没有主键同样,搜索表中的数据时,数据库引擎必须进行全表扫描,效率极其低下。]
更糟的是图书馆的图书愈来愈多,图书管理员的工做变得异常痛苦,有一天来了一个聪明的小伙子,他看到图书管理员的痛苦工做后,想出了一个办法,他建议将每本书都编上号,而后按编号放到书架上,若是有人指定了图书编号,那么图书管理员很快就能够找到它的位置了。
[给图书编号就象给表建立主键同样,建立主键时,会建立汇集索引树,表中的全部行会在文件系统上根据主键值进行物理排序,当查询表中任一行时,数据库首先使用汇集索引树找到对应的数据页(就象首先找到书架同样),而后在数据页中根据主键键值找到目标行(就象找到书架上的书同样)。]
因而图书管理员开始给图书编号,而后根据编号将书放到书架上,为此他花了整整一天时间,但最后通过测试,他发现找书的效率大大提升了。[在一个表上只能建立一个汇集索引,就象书只能按一种规则摆放同样。]测试

  
但问题并未彻底解决,由于不少人记不住书的编号,只记得书的名字,图书管理员无赖又只有扫描全部的图书编号挨个寻找,但此次他只花了20分钟,之前未给图书编号时要花2-3小时,但与根据图书编号查找图书相比,时间仍是太长了,所以他向那个聪明的小伙子求助。
[这就好像你给Product表增长了主键ProductID,但除此以外没有创建其它索引,当使用Product Name进行检索时,数据库引擎又只要进行全表扫描,逐个寻找了。]
聪明的小伙告诉图书管理员,以前已经建立好了图书编号,如今只须要再建立一个索引或目录,将图书名称和对应的编号一块儿存储起来,但这一次是按图书名称进行排序,若是有人想找“Database Management System”一书,你只须要跳到“D”开头的目录,而后按照编号就能够找到图书了。
因而图书管理员兴奋地花了几个小时建立了一个“图书名称”目录,通过测试,如今找一本书的时间缩短到1分钟了(其中30秒用于从“图书名称”目录中查找编号,另外根据编号查找图书用了30秒)。xml

图书管理员开始了新的思考,读者可能还会根据图书的其它属性来找书,如做者,因而他用一样的办法为做者也建立了目录,如今能够根据图书编号,书名和做者在1分钟内查找任何图书了,图书管理员的工做变得轻松了,故事也到此结束。blog

经过这个故事很容易理解索引的真正含义。假设咱们有一个Products表,建立了一个汇集索引(根据表的主键自动建立的),咱们还须要在ProductName列上建立一个非汇集索引,建立非汇集索引时,数据库引擎会为非汇集索引自动建立一个索引树(就象故事中的“图书名称”目录同样),产品名称会存储在索引页中,每一个索引页包括必定范围的产品名称和它们对应的主键键值,当使用产品名称进行检索时,数据库引擎首先会根据产品名称查找非汇集索引树查出主键键值,而后使用主键键值查找汇集索引树找到最终的产品。排序

确保每一个表都有主键
这样能够确保每一个表都有汇集索引(表在磁盘上的物理存储是按照主键顺序排列的),使用主键检索表中的数据,或在主键字段上进行排序,或在where子句中指定任意范围的主键键值时,其速度都是很是快的。
在下面这些列上建立非汇集索引:
1)搜索时常用到的;
2)用于链接其它表的;
3)用于外键字段的;
4)高选中性的;
5)ORDER BY子句使用到的;索引

增长普通索引和UNIQUE两种索引。其格式以下:
create index index_name on table_name (column_list) ;
create unique index index_name on table_name (column_list) ;
删除索引
drop index index_name on table_name ;
alter table table_name drop index index_name ;图片