前言
SQL索引有两种,聚集索引和非聚集索引
- 聚集索引存储记录是物理上连续存在,而非聚集索引是逻辑上的连续,物理存储并不连续
字典的拼音查询法就是聚集索引,字典的部首查询就是一个非聚集索引.
聚集索引和非聚集索引的根本区别是表记录的排列顺序和与索引的排列顺序是否一致
聚集索引一个表只能有一个,而非聚集索引一个表可以存在多个。
建立索引的原则:
1) 定义主键的数据列一定要建立索引。
2) 定义有外键的数据列一定要建立索引。
3) 对于经常查询的数据列最好建立索引。
4) 对于需要在指定范围内的快速或频繁查询的数据列;
5) 经常用在WHERE子句中的数据列。
6) 经常出现在关键字order by、group by、distinct后面的字段,建立索引。
如果建立的是复合索引,索引的字段顺序要和这些关键字后面的字段顺序一致,否则索引不会被使用。
7) 对于那些查询中很少涉及的列,重复值比较多的列不要建立索引。
8) 对于定义为text、image和bit的数据类型的列不要建立索引。
9) 对于经常存取的列避免建立索引
9) 限制表上的索引数目。对一个存在大量更新操作的表,所建索引的数目一般不要超过3个,最多不要超过5个。
索引虽说提高了访问速度,但太多索引会影响数据的更新操作。
10) 对复合索引,按照字段在查询条件中出现的频度建立索引。在复合索引中,记录首先按照第一个字段排序。
对于在第一个字段上取值相同的记录,系统再按照第二个字段的取值排序,以此类推。
因此只有复合索引的第一个字段出现在查询条件中,该索引才可能被使用,因此将应用频度高的字段,放置在复合索引的前面,会使系统最大可能地使用此索引,发挥索引的作用。
索引的不足之处
- 虽然索引大大提高了查询速度,同时却会降低更新表的速度,如对表进行INSERT、UPDATE和DELETE。因为更新表时,MySQL不仅要保存数据,还要保存一下索引文件。
建立索引会占用磁盘空间的索引文件。一般情况这个问题不太严重,但如果你在一个大表上创建了多种组合索引,索引文件的会膨胀很快。
索引只是提高效率的一个因素,如果你的MySQL有大数据量的表,就需要花时间研究建立最优秀的索引,或优化查询语句。
使用索引时,有以下一些技巧和注意事项:
索引不会包含有NULL值的列
只要列中包含有NULL值都将不会被包含在索引中,复合索引中只要有一列含有NULL值,那么这一列对于此复合索引就是无效的。
所以我们在数据库设计时不要让字段的默认值为NULL。
使用短索引
对列进行索引,如果可能应该指定一个前缀长度。
例如,如果有一个CHAR(255)的列,如果在前10个或20个字符内,多数值是惟一的,那么就不要对整个列进行索引。
短索引不仅可以提高查询速度而且可以节省磁盘空间和I/O操作。
索引列排序
MySQL查询只使用一个索引,因此如果where子句中已经使用了索引的话,那么order by中的列是不会使用索引的。
因此数据库默认排序可以符合要求的情况下不要使用排序操作;尽量不要包含多个列的排序,如果需要最好给这些列创建复合索引。
like语句操作
一般情况下不鼓励使用like操作,如果非使用不可,如何使用也是一个问题。
like “%aaa%” 不会使用索引,而like “aaa%”可以使用索引。
不要在列上进行运算
select * from users where YEAR(adddate)<2007;
将在每个行上进行运算,这将导致索引失效而进行全表扫描,因此我们可以改成
select * from users where adddate<‘2007-01-01’;
不使用NOT IN和<>操作
索引的建立时机
一般来说,在WHERE和JOIN中出现的列需要建立索引,但也不完全如此,
因为MySQL只对<,<=,=,>,>=,BETWEEN,IN,以及某些时候的LIKE才会使用索引。
因为在以通配符%和_开头作查询时,MySQL不会使用索引。
索引的使用
建立索引
create [UNIQUE|FULLTEXT] index index_name on tbl_name (col_name [(length)] [ASC | DESC] , …..);
示例:
alter table table_name ADD INDEX [index_name] (index_col_name,...)
CREATE INDEX paywayid_index ON pay_order_trade (paywayid)
组合索引
CREATE INDEX idx_example
ON table1 (col1 ASC, col2 DESC, col3 ASC)
示例:
ALTER TABLE people ADD INDEX lname_fname_age (lame,fname,age);
最左前缀:顾名思义,就是最左优先,
上例中我们创建了lname_fname_age多列索引,相当于创建了(lname)单列索引,(lname,fname)组合索引以及(lname,fname,age)组合索引。
删除索引
DROP INDEX index_name ON tbl_name;
alter table table_name drop index index_name;
删除主键(索引)比较特别:
alter table t_b drop primary key;
查询索引(均可)
show index from table_name;
show keys from table_name;
desc table_Name;