Mysql单表访问方法,索引合并,多表连接原理,基于规则的优化,子查询优化( 四 )

  • 对上述查询中获取的每一条记录 , 都分别到被驱动表中查找匹配的记录 。

  • Mysql单表访问方法,索引合并,多表连接原理,基于规则的优化,子查询优化

    文章插图
    这样就将夺多表的连接查询 , 转化为多次单表查询 , 其中驱动表只需要访问依次 , 但是被驱动表需要访问多次 , 访问的次数取决于驱动表执行单表查询后的结果集具备多少条记录 。
    这或许就是为什么外连接建议使用小表join大表
    6.2 使用索引加载连接速度在获取到驱动表的单表查询后的一条记录后 , 需要在被驱动中找到符合条件的记录
    select * from a left join b on a.id=b.id where a.name like '%陈%' and b.age>10
    首先是执行select * from a wherea.name like '%陈%' ,在a表中得到a.id=1和a.id=2的记录 , 然后去b中执行select * from b where b.id=1 and b.age>10 select * from b where b.id=2 and b.age>10
    如果id是b表的索引 , 这时候就可以使用到索引 , 或者age是b表的索引也同样可以使用到索引,由于查询的是*如果索引B+树叶子节点的内容无法覆盖 , 那么将进行回表
    6.3 基于块的嵌套连接查询上面我们说到嵌套循环连接 , 每次在驱动表中获取到一条记录都需要去被驱动表中进行查询 , 如果驱动表查询到了很多条数据 , 被驱动表数据量很大 , 且无法使用到被驱动表的索引 , 那么需要对被驱动表进行多次全表扫描 , 导致IO代价非常大 , 所以需要减少被驱动表的访问次数
    解决的办法便是 , 将被驱动表的记录加载到内存 , 一次性和驱动表中的多条记录进行匹配 。mysql有一个join buffer,在执行连接查询的时候申请一块固定大小的内存 , 先把若干条驱动表结果集 , 转载join buffer中 , 然后开始扫描被驱动表 , 然后被驱动表的记录一次性与join buffer进行匹配 , 由于匹配是在内存中进行的 , 这样可以显著减少被驱动表的io代价 。
    Join buffer的大小可以通过join_buffer_size,如果实在无法在被驱动表上使用到较好的索引 , mysql服务所在的机器内存比较大 , 可以调大对连接查询进行优化 。
    Join Buffer并不会存储驱动表的所有字段 , 只会存储涉及到查询条件的字段和查询列表中的字段 , 所以尽量不要使用select * 可以让join buffer存放更多的数据
    五丶基于规则的优化&子查询优化1条件化简