全表扫描(Full Table Scan)就是数据库为了检索到我们查找的数据而逐行的去扫描表中的所有记录。很明显,全表扫描是一种非常慢的SQL查询。想象一下,对一张百万级的表进行全表扫描性能有多差!使用索引可以有效避免全表扫描。但是往往建了索引,还是没有想象中那么快,可以总结下看看是不是下列原因呢 1:统计信息还没有更新
通常,数据库的统计信息要与表数据和索引数据保持一致。但是,因为一些原因导致表或索引的统计信息没有及时更新,结果就有可能造成全表扫描。这是因为大多数RDBMS(关系型数据库)的查询优化器会根据这些统计信息来计算是否应该使用索引。如果没有这些统计信息或统计信息不准确,RDBMS可能会错误的认为执行全表扫描比使用索引更高效
2:“选择性”是描述列值数据分布情况的一个重要属性。“选择性”和“基数”(cardinality)是两个密不可分的概念。“基数”就是一列中唯一值的数量,对于有唯一约束的列,“基数”等于表的总行数。 例如:现在我们要查询所有女性的名字,由于性别只有男性和女性两种情况,所以女性占比是50%的可能性很大。那我们就假设确实有50%(5000)是女性。如果查找索引的话,数据库为了查找出所有女性就需要访问索引5000次。要知道访问索引也是需要消耗时间和资源的。所以这种情况,直接去做全表扫描可能会更快一些。可以看到,数据库的查询优化器会根据“选择性”的高低来决定使用索引还是直接全表扫描。
3:没有WHRER子句
如果查询语句没有过滤结果集的WHRER子句,会执行全表扫描。
4:WHRE子句中使用了“比较”操作,而阻止了数据库使用索引!
--使用不等于操作(!= 或 <>)。
WHERE NAME <> 'Jesus'
--因为索引只能用于查找表中有什么,而不能用于查找表中没有什么。
--使用`NOT`操作符。
WHERE NOT NAME 'Jesus' 。
--通配符出现在字符串比较的开始位置。
WHERE NAME LIKE '%programmer%' 。
--以哪个字母开始都不清楚,索引也无能为力了。
5:最左前缀匹配原则
对于多列的混合索引(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)的最左前缀。
6:最后,使用索引有什么代价?
那么,创建数据库索引有什么缺点?首先,占用空间。你的表越大,索引需要的空间就越大。另外会影响数据库性能,你对数据表进行增删改操作,同样的操作还要在索引上执行一次。
1261

被折叠的 条评论
为什么被折叠?



