zoukankan      html  css  js  c++  java
  • mariadb使用with子句重写SQL性能提升5倍

    几个月前,我们有个产品的开发反馈了个问题,说有个组织结构的查询很慢,几千行的复杂关联需要1秒钟,表示太慢了,原语句如下:

    SELECT
      org.org_id,
      org.dimension,
      org.org_code,
      org.org_name,
      org.parent_id,
      org.manage_id,
      org.org_cate,
      org.org_level,
      org.org_order,
      org.org_path,
      org.position_code,
      org.ext_id,
      org.remark,
      pos.position_name,
      parent.org_code AS parent_code,
      parent.org_name AS parent_name,
      manage.org_code AS manage_code,
      manage.org_name AS manage_name,
      org. STATUS
    FROM
      tsys_organization org
    LEFT JOIN tsys_position pos ON org.position_code = pos.position_code
    LEFT JOIN tsys_organization parent ON org.parent_id = parent.org_id
    LEFT JOIN tsys_organization manage ON org.manage_id = manage.org_id
    WHERE 
      org.org_id IN(
        SELECT
          org.org_id
        FROM
          tsys_organization org
        JOIN tsys_user us ON us.user_id ='admin'
        
        UNION
          SELECT
            ou.org_id
          FROM
            tsys_org_user ou
          WHERE
            user_id ='admin'
          UNION
            SELECT
              org.org_id
            FROM
              tsys_organization org
            JOIN pos_user_view po ON po.user_id ='admin'
      )
    AND org. STATUS = 0
    ORDER BY
      org.org_order

    够复杂的,看了下执行计划,确实有个子句没有物化导致i/o访问次数下不来,于是对该子查询使用with重写如下:

    with a as (
        SELECT
          org2.org_id
        FROM
          tsys_organization org2
        JOIN tsys_user us ON us.user_id ='admin'
        
        UNION all
          SELECT
            ou.org_id
          FROM
            tsys_org_user ou
          WHERE
            user_id ='admin'
          UNION all
            SELECT
              org1.org_id
            FROM
              tsys_organization org1
            JOIN pos_user_view po ON po.user_id ='admin'
      )
    SELECT
      org.org_id,
      org.dimension,
      org.org_code,
      org.org_name,
      org.parent_id,
      org.manage_id,
      org.org_cate,
      org.org_level,
      org.org_order,
      org.org_path,
      org.position_code,
      org.ext_id,
      org.remark,
      pos.position_name,
      parent.org_code AS parent_code,
      parent.org_name AS parent_name,
      manage.org_code AS manage_code,
      manage.org_name AS manage_name,
      org. STATUS
    FROM
      tsys_organization org
    LEFT JOIN tsys_position pos ON org.position_code = pos.position_code
    LEFT JOIN tsys_organization parent ON org.parent_id = parent.org_id
    LEFT JOIN tsys_organization manage ON org.manage_id = manage.org_id
    WHERE 
      org.org_id IN (select org_id from a)
    AND org. STATUS = 0
    ORDER BY
      org.org_order

    因为mariadb的with子句会强制物化为临时表,改写后,0.2秒执行完成(oracle 12.2开始也支持强制,在此之前需要加materialized提示)。

  • 相关阅读:
    实例化对象
    面向对象
    合并类动态规划——石子合并(洛谷1880)
    合并类动态规划——能量项链(洛谷1063)
    multiplicationoverview
    cadence 工艺库各文件夹所包含的内容
    C语言读入文件的函数列举
    一篇工程师的感悟(转载)
    验证汇总一些缩写代码含义
    Verilog代码覆盖率检查
  • 原文地址:https://www.cnblogs.com/zhjh256/p/10906683.html
Copyright © 2011-2022 走看看