› MySQL 5.5 Community Server
› MySQL 5.6 Community Server
› Percona Configuration Wizard
› XtraBackup 搭建主从复制
Great Sites on MySQL
› Percona
› MySQL Performance Blog
› Severalnines
推荐管理工具
› Sequel Pro
› phpMyAdmin
推荐书目
› MySQL Cookbook
MySQL 相关项目
› MariaDB
› Drizzle
参考文档
› http://mysql-python.sourceforge.net/MySQLdb.html
mrjnamei
V2EX  ›  MySQL

这个 SQL 有优化空间吗

  •  
  •   mrjnamei · May 23, 2022 · 3890 views
    This topic created in 1592 days ago, the information mentioned may be changed or developed.
    
    select a.c_id from a
    inner join b on a.c_id = b.c_id
    inner join (
        select c.c_id from c
        union
        select d.c_id from d
    ) t on a.c_id = t.c_id 
    
    

    关系可以看做是:

    a 且 b 且 ( c 或 d )

    8 replies  •  2022-05-26 17:25:57 +08:00
    BiChengfei
        1
    BiChengfei  
       May 23, 2022
    你这个 SQL ,问题应该出在在内存中创建了 c 和 d 的交集的临时表,导致无法命中索引,执行的全表查询。那么我的想法就是不在内存中创建临时表
    可执行以下 SQL ,效果应该相同:
    ```
    select
    a.c_id
    from a
    inner join b on a.c_id = b.c_id
    inner join c on c.c_id = a.c_id
    union
    select
    a.c_id
    from a
    inner join b on a.c_id = b.c_id
    inner join d on d.c_id = a.c_id
    ```
    BiChengfei
        2
    BiChengfei  
       May 23, 2022
    https://img.gejiba.com/images/64758a40d86b4252f789058746a61f31.png
    可以通过连接关系,理解上面的 SQL
    asmile1993
        3
    asmile1993  
       May 23, 2022
    执行计划呢?
    asmile1993
        4
    asmile1993  
       May 23, 2022
    c 、d 表数据量不大的情况下用 1 楼的方法没有问题,但要执行两次,再 union 起来,感觉代价还是大了点。用 exists 去判断好了(在 1 对多的情况下也可以避免数据重复)

    select a.c_id
    from a inner join
    b on a.c_id = b.c_id
    where exists (
    select 1
    from c
    where c.c_id = a._cid
    )
    or exists (
    select 1
    from d
    where d.c_id = a._cid
    )
    leonhao
        5
    leonhao  
       May 23, 2022
    只取 a.c_id 为啥要 join ,直接用 in 或者 exists ,join 可能产生重复数据
    c6h6benzene
        6
    c6h6benzene  
       May 23, 2022 via iPhone
    c 或 d 里面一定要有?我可能会 left join c 、left join d 然后其他地方写条件。
    haah
        7
    haah  
       May 23, 2022
    你的优化是指数据量的优化吧?
    mrjnamei
        8
    mrjnamei  
    OP
       May 26, 2022
    回复一下大佬们:
    业务场景是动态拼接 SQL. 根据页面编辑器组装查询条件,我拼出的 SQL 就是类似上面发的 SQL. 数据库是千万 /亿级别的数据量(starrocks), 之前用过 子查询,效率非常低,数据过大的场景可能会阻塞 IO. 1 楼老哥提供的思路实质上是集合的展开运算,但是在拼装 SQL 上会有比较大的压力。
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   2478 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 02:01 · PVG 10:01 · LAX 19:01 · JFK 22:01
    ♥ Do have faith in what you're doing.