什么是过滤列
过滤列是一种存在于where子句中,同时上面也有索引,能起到过滤数据,但是不能在索引片中生效仅能增加索引片厚度的一种列。目的是减少回表。
注:从过滤列的定义可知,并不是所有的列都能够在索引片中发挥作用,仅仅只是占位。
如何判断是否是过滤列
1. 首先我们需要查看目标列是否在索引中,然后再查看索引中列的顺序,并且要从左到右查看,因为列在索引中越靠左对索引效率影响越大,比如索引idxname(a,b,c,d)。
2. 查看SQL语句中where子句中是否有以下情况:
(1)是否至少拥有一个简单的谓词(比如a = ’xxx’)。如果有,这个列就是匹配列;如果没有,这个列以及后面的索引列都是非匹配列。
(2)如果是个范围谓词(比如b > xxx),那么除了这个列以外,剩下的列都是非匹配列
(3)如果在最后一个匹配列之后的非匹配索引列,也有一个简单的谓词(比如c = ’xxx’),那么这个列就是过滤列。
为了方便理解,我们来看看这个SQL:
create index idx_stud on students(classno,grade,location,age);
select studname from students where classno = 101 and grade > 90 and location = ’bj’;
1. classno这个索引列在索引的第一个,并且是个等值谓词,所以是个最简单的谓词条件,满足第一个条件,因此classno是匹配列,将在索引片中发挥作用。
2. grade这个索引列在索引的第二个,而且between是个范围谓词,也满足第二个条件,因此grade是匹配列,将在索引片中发挥作用。
3. location这个索引列在索引的第三个,并且是个等值谓词,虽然是个最简单的谓词条件,但是它排在grade这个范围谓词的后面,由第二和第三个条件可知,它不能参与匹配过程,也不会在索引片中发挥作用(仅增加了索引片厚度),但参与了索引过滤,所以是过滤列。
但是不要因为它是过滤列而且不参与索引匹配便觉得它不重要,location列几乎和classno、grade两列同等重要。
综上所述,该SQL一共有两个匹配列(classno和grade)和一个过滤列(location),所以当这个SQL访问的表中有数据同时满足这三个谓词条件时,才会访问表中的数据。如果:
1. where子句只有classno和location,如where classno = 101 and location = ’bj’,classno依旧是匹配列,location依旧是过滤列。
2. where子句的grade是等值条件,如where classno = 101 and grade = 90 and location = ’bj’,这三列都是匹配列。
3. where子句只有grade和location,如where grade > 90 and location = ’bj’,grade和location只能是过滤列,并且索引片的厚度就是整个索引的大小。