全表扫描(Full Table Scan)就是数据库为了检索到咱们查找的数据而逐行的去扫描表中的全部记录。很明显,全表扫描是一种很是慢的SQL查询。想象一下,对一张百万级的表进行全表扫描性能有多差!使用索引能够有效避免全表扫描。sql
让咱们看一些会形成进行全表扫描的状况:数据库
一般,数据库的统计信息要与表数据和索引数据保持一致。可是,由于一些缘由致使表或索引的统计信息没有及时更新,结果就有可能形成全表扫描。这是由于大多数RDBMS(关系型数据库)的查询优化器会根据这些统计信息来计算是否应该使用索引。若是没有这些统计信息或统计信息不许确,RDBMS可能会错误的认为执行全表扫描比使用索引更高效。性能
若是查询语句没有过滤结果集的WHRER子句,会执行全表扫描。优化
有些状况,即便建立了索引还会执行全表扫描。spa
虽然查询语句有WHERE子句,可是WHERE子句中使用的列没有匹配索引的"领导列"(leading column),就会执行全表扫描。领导列又称最左列(leftmost column),见下一节“最左前缀匹配原则”。.net
即便WHERE子句中使用了索引的最左列,仍有可能执行全表扫描。这通常是因为WHRE子句中使用了“比较”操做,而阻止了数据库使用索引!下面列举几个会形成这种状况的例子:code
使用不等于操做(!= 或 <>)。blog
例如: WHERE NAME <> 'Jesus'索引
由于索引只能用于查找表中有什么,而不能用于查找表中没有什么。字符串
使用`NOT`操做符。
例如:WHERE NOT NAME 'Jesus' 。缘由同上。
通配符出如今字符串比较的开始位置。
例如:WHERE NAME LIKE '%programmer%' 。
以哪一个字母开始都不清楚,索引也无能为力了。
最左前缀匹配原则
对于多列的混合索引(composite index),只有符合最左前缀(leftmost prefix)的索引才能被查询优化器使用。好比,某个3列的混合索引(col1,col2,col3),只有下面三种状况可使用到索引: (col1), (col1, col2),和 (col1, col2, col3)。
对于下面的查询语句:
SELECT * FROM tbl_name WHERE col1=val1; SELECT * FROM tbl_name WHERE col1=val1 AND col2=val2; SELECT * FROM tbl_name WHERE col2=val2; SELECT * FROM tbl_name WHERE col2=val2 AND col3=val3;
只有前两个SELECT语句使用到了索引,第3个和第4个查询虽然使用了索引列,可是(col2)和(col2,col3)不是混合索引(col1, col2, col3)的最左前缀。
相关阅读: