V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
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
grittiness
V2EX  ›  MySQL

MySQL 查询在原本的 SQL 外再包一层就会导致查询巨慢有什么解决方式么?

  •  
  •   grittiness · 2019-09-20 17:40:30 +08:00 · 4920 次点击
    这是一个创建于 1896 天前的主题,其中的信息可能已经有所发展或是发生改变。

    在公司的项目里面遇到了一个情况,是一个列表的 SQL 查询,我写好 SQL 直接丢进 MySQL 执行,查询时间是 0.469s

    在放进 MyBatis 实际执行的过程中发现分页插件在 SQL 我写的 SQL 的外围再包了一层select count(1) from ()以后查询就变得巨慢,几十秒都出不来结果。。。😂

    然后我在调试过程中发现如果把原 SQL 中的where语句都删掉,放进外包一层select count(1) from()以后查询就变得正常了,查询时间是 0.755s

    现在就很好奇这是为什么以及这种外包一层 select 导致查询巨慢的情况需要怎么解决?网上搜了一下,找不到什么有用的资讯,数据库方面有点菜,因此来请教下各位 v2 的大佬,谢谢!

    12 条回复    2019-09-21 15:03:36 +08:00
    zjlletian
        1
    zjlletian  
       2019-09-20 17:49:20 +08:00
    可能是包了一层就不走索引了?? explain 看看
    LlvlDd
        2
    LlvlDd  
       2019-09-20 17:54:22 +08:00
    使用 count(*) 有神秘加成
    grittiness
        3
    grittiness  
    OP
       2019-09-20 17:56:44 +08:00
    @zjlletian 要是执行原本带了 where 的 SQL,explain 能一直执行到数据库强制断开连接都出不来结果,如果我去掉 where 用 explain 看的话是有走索引的
    grittiness
        4
    grittiness  
    OP
       2019-09-20 17:57:34 +08:00
    @LlvlDd count(*) 也一样 出不来结果
    Vegetable
        5
    Vegetable  
       2019-09-20 18:01:46 +08:00
    可以尝试搜索 子查询 索引失效 这两个关键字哦
    StarkWhite
        6
    StarkWhite  
       2019-09-20 18:02:07 +08:00
    应该是子查询临时表问题,不加 WHERE 会被查询引擎优化成没有子查询的语句,
    不过这也只是推测,具体的 SQL 语句发出来看看呗
    Rekkles
        7
    Rekkles  
       2019-09-20 18:02:59 +08:00
    100ms 都慢了 你这 几百毫秒 ... 我很好奇你说的变慢是多慢
    grittiness
        8
    grittiness  
    OP
       2019-09-20 18:19:01 +08:00
    @Rekkles left join 了 20 张表,还有 group by,所以感觉 1m 以内没啥问题把
    @StarkWhite SQL 太复杂了,不太合适发上来,left join 了 20 张表,可以私发给你看看。。
    chengyiqun
        9
    chengyiqun  
       2019-09-20 18:32:05 +08:00
    这个之前我也碰到过, 通过客户名称定位客户时, 本来就是模糊查询(不走索引) 包一层更慢. 索性手动分页, 计算好 limit 和 offset... 快多了, 原本直接服务超时, 改过以后, 400ms.
    ```java
    Integer count;
    if ( (
    "2".equals(qryInMap.get("custTypeFlag")) || "3".equals(qryInMap.get("custTypeFlag"))
    ) &&
    (
    !ObjectIsNull.check(qryInMap.get(Constants.HUMP_PROD_INST_ID)) || !ObjectIsNull.check(qryInMap.get(Constants.HUMP_ACC_NBR)) || !ObjectIsNull.check(qryInMap.get(Constants.HUMP_ACCOUNT))
    )
    ) {
    List<Long> custIdsList1 = this.selectList(null, QRY_CUST_LIST_NAME_SPACE + ".qryUseCustIdsOrPayCustIdsByProdInst", qryInParamMap);
    qryInParamMap.put("custIds", custIdsList1);
    qryInParamMap.remove(Constants.HUMP_PROD_INST_ID);
    qryInParamMap.remove(Constants.HUMP_ACC_NBR);
    qryInParamMap.remove(Constants.HUMP_ACCOUNT);
    qryInParamMap.remove("custTypeFlag");
    count = this.selectOne(null, QRY_CUST_LIST_NAME_SPACE + ".countCustWithoutParam", qryInParamMap);
    } else {
    count = this.selectOne(null, QRY_CUST_LIST_NAME_SPACE + ".countCustWithoutParam", qryInParamMap);
    }
    if (pageMap != null) {
    pageMap.setTotalRecord(count);
    pageMap.setTotalPage(count % pageMap.getPageSize() == 0? count/pageMap.getPageSize() : count/pageMap.getPageSize() + 1);
    if (count == 0 || (pageMap.getStartNum() > count)) {
    return new ArrayList<Map<String,Object>>();
    }
    qryInParamMap.put("startNum", pageMap.getStartNum());
    qryInParamMap.put("pageSize", pageMap.getPageSize());
    } else {
    // 兼容政企客户类型不传 分页
    if (count == 0) {
    return new ArrayList<Map<String,Object>>();
    }
    qryInParamMap.put("startNum", 0);
    qryInParamMap.put("pageSize", 65535);
    }
    List<Long> custIdsList = this.selectList(null, QRY_CUST_LIST_NAME_SPACE + ".queryCustIdsWithoutParam", qryInParamMap);
    qryInParamMap.put("custIds", custIdsList);
    List<Map<String, Object>> customers = this.selectList(null, QRY_CUST_LIST_NAME_SPACE + ".queryCustListWithCustIds", qryInParamMap);

    ```
    StarkWhite
        10
    StarkWhite  
       2019-09-21 10:18:43 +08:00
    @grittiness SQL 复杂和私发有啥关系?如果说格式问题,复制粘贴到能格式化 SQL 的工具就好了。
    而且我不一定能帮你解决哦,发出来可能别的 V 友会帮你解决
    grittiness
        11
    grittiness  
    OP
       2019-09-21 14:35:38 +08:00
    @StarkWhite 因为是公司的代码,我怕发上来不太合适.... 😂
    @chengyiqun 谢谢 学习下
    StarkWhite
        12
    StarkWhite  
       2019-09-21 15:03:36 +08:00
    @grittiness 把表名换掉,字段名也可以换掉
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1098 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 22:38 · PVG 06:38 · LAX 14:38 · JFK 17:38
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.