V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
cpdyj
V2EX  ›  PostgreSQL

请问这个查询会被优化吗?

  •  
  •   cpdyj · 2018-07-27 21:57:02 +08:00 · 2146 次点击
    这是一个创建于 2311 天前的主题,其中的信息可能已经有所发展或是发生改变。

    请问下面这个 SQL 系统会不会扫描 Student.gender != 1 的记录?这些记录似乎完全没有被扫描的必要啊(反正最后也会被 where 过滤掉)

    select * 
    from Student left join Class
    on Student.class = Class.id
    where Student.gender = 0
    

    谢谢

    2 条回复    2018-08-16 17:04:55 +08:00
    zjp
        1
    zjp  
       2018-07-28 12:57:34 +08:00 via Android   ❤️ 1
    这和 gender 上有没有索引,数据量多大都有关系

    explain 一下看执行计划就知道了
    whx20202
        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 执行计划都拿出来,是真实的。
    研究一下的话,还是很有帮助的
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2162 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 01:16 · PVG 09:16 · LAX 17:16 · JFK 20:16
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.