请问下面这个 SQL 系统会不会扫描 Student.gender != 1 的记录?这些记录似乎完全没有被扫描的必要啊(反正最后也会被 where 过滤掉)
select *
from Student left join Class
on Student.class = Class.id
where Student.gender = 0
谢谢
1
zjp 2018-07-28 12:57:34 +08:00 via Android 1
这和 gender 上有没有索引,数据量多大都有关系
explain 一下看执行计划就知道了 |
2
whx20202 2018-08-16 17:04:55 +08:00
一楼说的对,我再冗余几句,优化器生成执行计划非常复杂
这种场景下,class.id 要有索引,主键是会自动加的,所以是废话 然后 gender 再有索引的话,一般来说就是最好的执行计划 当然这也跟表大小有关系,如果两个表都很小,可能会直接全表扫描, 还就是也跟数据分布有关系,假如你 student 表有点大,比如一百万,但是基本 99 万都是女的( gender=0 ) 优化器一看你这索引区分度太低( 100 万有 99 万都是 0 ),那也有可能不走索引(当然这个有可能用 ramdom_page_cost 或者 effective_cache_size 等参数 来影响优化器计算查询 cost,进而影响判断) 一般来说,不抬杠的话,性别是一半一半,这种区分度不太好(相比而言,学号,身份证号这种区分度极好,基本是唯一的) 有可能表很大的情况下,你这个查询可能会很挫,如果业务允许,可以建议把 name 学号 也带到 sql 里。 最后,postgresql 的 explain 非常强大,有的数据库 explain 就是优化器猜测一个执行计划,未必是真的运行时执行计划 而 postgresql 有 “ explain analyze ” 命令,这个是把 runtime 执行计划都拿出来,是真实的。 研究一下的话,还是很有帮助的 |