iis服务器助手广告广告
返回顶部
首页 > 资讯 > 数据库 >Mysql大数据量查询优化思路详析
  • 570
分享到

Mysql大数据量查询优化思路详析

2024-04-02 19:04:59 570人浏览 安东尼
摘要

目录1. 千万级别日志查询的优化2. 几百万黑名单库的查询优化3. mybatis批量插入处理问题项目场景: Mysql大表查询优化,理论上千万级别以下的数据量mysql单表查询性能

项目场景:

Mysql大表查询优化,理论上千万级别以下的数据量mysql单表查询性能处理都是可以的。

问题描述:

在我们线上环境中,出现了mysql几千万级别的日志查询、几百万级别的黑名单库查询分页查询及条件查询都慢的问题,针对Mysql表优化做了一些优化处理。

原因分析:
首先说一下日志查询,在Mysql中如果索引加的比较合适,走索引情况下千万级别查询不会超过一秒,Mysql查询的速度和检索的数据条数有关。在Mybatis中,分页查询是先执行Count记录总数,再执行limit a,b 的方式来进行的,而Mysql的Count计数方式是将所有的数据过滤一遍进行累加,因此当日志表数据过千万时,统计一次就是十几秒钟的时间(这里是服务器环境,本地情况下甚至是几分钟)。
limit a,b的方式也一样,Mysql查询时会先一条一条数到第a条,然后向后再数b条作为查询结果,因此当起始行数越来越大时查询同样会变得很慢,也就是当你点第一页时可能一下就查出来了,当你点最后一页的时候可能几十秒才能查出来。
黑名单库查询优化同理,也是需要通过条件优化。
在进行大批量数据落库时,使用的Mybatis批量插入,发现当批次数据超过3000时速度会急剧变慢,这是一个Mybatis娘胎里自带的问题,也需要进行解决。

解决方案:

这里只简单说明优化的几个方向。

1. 千万级别日志查询的优化

  1. 首先说下日志查询,重点是优化无条件是分页查询,在无条件时,不使用MyBatis的分页插件,而是自己手写一个分页查询,由于MySql的count耗时过长,我们先优化他。
  2. 优化Count:日志表的数据只增,不会出现中间某条删除,所以他的数据可以理解成是连续的,我们可以在内存中直接进行计数,记录count总数,或者给表添加一个自增的ID字段,直接select max(id)就是总数量,这样count查询的效率会提升到毫秒级别。
  3. 自定义分页查询:分页查询中使用优化后的count记录总数,然后使用(page - 1)* pageSize + 1公式计算出当前页的最小ID,然后将limit a,b 的Sql语句改为where ID > 最小ID limit b的方式,这样查询就会走索引先将小于最小ID的数据过滤掉,再进行查询,经过第二步和第三步的优化后分页查询效率缩短到了一秒内,并且不会随着页数的增长而变慢。
  4. 条件查询:条件查询只能设置合适的索引,另外慎用like '%条件%‘的方式进行匹配查询,这样会导致索引失效全局检索,模糊查询尽量使用like '条件%' 的方式进行最左匹配,也可以使用explain+sql语句 的方式来查看sql语句的执行效率,是否走了所有啥的来针对性的优化,加好合适的索引、优化查询语句后通常一千万以内的数据查询效率会在3秒内。

粘出自定义分页查询结果封装:

 // 手动count
                Integer total = logPushService.queryBackCount(resMap);//查询数量
                // 手动查询结果
                List<InterceptInfo> ls = logPushService.queryBackByPage(resMap);
                PageInfo pageInfo = new PageInfo();
                pageInfo.setTotal(total);
                pageInfo.setPageSize(limit);
                pageInfo.setList(ls);
                pageInfo.setPageNum(pn);

2. 几百万黑名单库的查询优化

  • 黑名单库查询优化只能通过加合适的索引和优化SQL语句来优化,百万级别数据松松的在Mysql和Mybatis的承受范围内,这里是由于黑名单库不是使用递增的,有可能会增加也有可能会删除,所以只能使用优化索引和SQL的方式进行优化。
  • 另外,Mybatis框架提供了重写分页查询count统计语句的方法,只需要将count语句命名为查询方法_COUNT即可,例如分页查询的语句方法是query,那么重写的统计方法即为query_COUNT

 <select id="query_COUNT" parameterType="java.util.Map" resultType="java.lang.Long">
        SELECT
        count(0)
        from nms_intercept_info${map.week}
        where 1=1
        <if test="map.id!=null and map.id!='' ">
            AND id>#{map.id}
        </if>
        <if test="map.url!=null and map.url!='' ">
            AND spliturl=#{map.url}
        </if>
        <if test="map.startTime!=null and map.startTime!='' ">
            AND time <![CDATA[>=]]> #{map.startTime}
        </if>
        <if test="map.endTime!=null and map.endTime!='' ">
            AND time <![CDATA[<=]]> #{map.endTime}
        </if>
        <if test="map.type!=null and map.type!='' ">
            AND bigType = #{map.type}
        </if>
    </select>

3. Mybatis批量插入处理问题

Mybatis批量插入语句中的类集合大小不能超过五千,三千是最佳,这是测试出来的结果,考虑到的原因是Mybatis会将类做反射,这个太影响效率,因此批量插入时要注意这个,如果你能够三千三千的批量处理就限制一下,不要让每批数据超过3000,数据量过大时也可以使用异步非阻塞的方式来插入。
异步非阻塞代码(只是步骤样例,存在代码缺失):

    // 执行全量HMD导入任务的线程池
    public final static ExecutorService importHasPool = Executors.newFixedThreadPool(10);
    public final static CompletionService<DoexcelResult> importHasPoolService = new ExecutorCompletionService<>(importHasPool);
    
   public synchronized DoExcelResult example() {
            // 开始执行导入
            // 写到这里面方法最后会自动关闭
            long startTime = System.currentTimeMillis();
            // 定义一个集合,记录Callable的执行结果,Callable是带返回值的Runable
            List<Future<DoExcelResult>> futures = new ArrayList<>();
            while ((str = reader.readLine()) != null) {
                if (list.size() > 5000) { // 5000插入一次
                    List<String> list1 = CollectionUtil.copyDepth(list);
                    list.clear();
                    // BlackInfoHasImportlCallable是实现了Callable接口的实现类,Callable是带返回值的Runable
                    Future submit = SysThreadPoolCenter.importHasPoolService.submit(new BlackInfoHasImportlCallable(list1, blacklistInfoMapper));
                    futures.add(submit);
                }
            }
            
            // 等待执行结果
            for (Future<DoExcelResult> future : futures) {
                try {
                // 2. futrue.get时会获取返回值,线程没执行完毕就等待等待执行结果
                    DoExcelResult doExcelResult = future.get();
                    result.setSuccessNum(result.getSuccessNum() + doExcelResult.getSuccessNum());
                    result.setContinueNum(result.getContinueNum() + doExcelResult.getContinueNum());
                    result.setErrorNum(result.getErrorNum() + doExcelResult.getErrorNum());
                } catch (Exception e) {
                    log.error(e);
                }
            }
            // 循环结束代表所有线程执行完毕
            result.setTimeCon((System.currentTimeMillis() - startTime)/1000.0);
            BlacklistService.isDoing = false;
        } catch (Exception e) {
            BlacklistService.isDoing = false;
            log.error(e);
        }
        BlacklistService.isDoing = false;
        return result;
    }

限制每批3000条:

 if (ls.size() >= 3000) {
            //每次保存3000
            double sum = Math.ceil(ls.size() / 3000f);
            for (int i = 0; i < sum; i++) {
                total += blacklistDao.saveBatch(ls.subList(i * 3000, ((i + 1) * 3000) > ls.size() ? ls.size() : (i + 1) * 3000));
            }
        } else {
            total = blacklistDao.saveBatch(ls);
        }

如果你数据库用的不是mysql,而是CK或者其他的大数据处理数据库,批量插入可能要求每秒几万条几十万条,这时就不再适合使用Myabtis框架了,建议使用JDBC连接的方式,自己写代码拼接sql语句,再使用jdbc连接执行(使用线程池),效率上会快很多。

到此这篇关于Mysql大数据量查询优化思路详析的文章就介绍到这了,更多相关Mysql大数据量查询优化内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

您可能感兴趣的文档:

--结束END--

本文标题: Mysql大数据量查询优化思路详析

本文链接: https://www.lsjlt.com/news/162315.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Mysql大数据量查询优化思路详析
    目录1. 千万级别日志查询的优化2. 几百万黑名单库的查询优化3. Mybatis批量插入处理问题项目场景: Mysql大表查询优化,理论上千万级别以下的数据量Mysql单表查询性能...
    99+
    2024-04-02
  • mysql大数据量查询怎么优化
    在处理大数据量查询时,可以通过以下几种方法来优化查询性能: 使用合适的索引:通过在查询字段上创建索引,可以大大减少查询所需的时间...
    99+
    2024-04-12
    mysql
  • mysql大数据查询优化的示例分析
    这篇文章给大家分享的是有关mysql大数据查询优化的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。mysql数据量少,优化没必要,数据量大,优化少不了,不优化一个查询10...
    99+
    2024-04-02
  • MySQL千万级数据查询的优化技巧及思路
    随着数据量的不断增长,MySQL千万级数据查询的优化问题也日益引人注目。在这篇文章中,我们将深入探讨MySQL千万级数据查询优化的方法和技巧,以帮助开发者更好地优化MySQL性能。 一、数据库设计 数据库设计是优化查询性能的关键,以下是一些...
    99+
    2023-09-03
    数据库 mysql java
  • MySQL查询中分页的思路和优化
    这篇文章主要介绍“MySQL查询中分页的思路和优化”,在日常操作中,相信很多人在MySQL查询中分页的思路和优化问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”MySQL查询中...
    99+
    2024-04-02
  • MySQL 大数据in查询该怎么优化
    对于 MySQL 中的大数据 IN 查询,可以使用以下方法进行优化: 尽可能使用索引。如果使用 IN 操作符的字段有索引,MySQL 将会使用索引来加速查询。 尽量使用常量作为 IN 操作符中的参数,而不是使用子查询或者表达式。因为 M...
    99+
    2023-09-16
    mysql 大数据 数据库
  • 分析MySQL优化思路
    这篇文章主要讲解了“分析MySQL优化思路”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“分析MySQL优化思路”吧!     ...
    99+
    2024-04-02
  • MySQL大数据查询性能优化的示例
    这篇文章将为大家详细讲解有关MySQL大数据查询性能优化的示例,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。MySQL性能优化包括表的优化与列类型选择,表的优化可以细分为...
    99+
    2024-04-02
  • MySQL查询缓存优化示例详析
    目录一、概述二、查询优化内容1、查询缓存的原理2、查询缓存的优缺点3、不能应用查询缓存的内容4、查询缓存相关的服务器变量5、SELECT语句的缓存控制6、查询缓存相关的状态变量7、查询的优化的检查路线8、命中率和内存使用...
    99+
    2024-04-02
  • 如何通过索引优化PHP与MySQL的复杂查询和大数据量查询?
    引言:随着互联网的快速发展,数据量的爆炸式增长成为了一个普遍的问题。对于使用PHP和MySQL进行复杂查询和处理大数据量的项目来说,索引优化是提高查询性能和响应时间的重要手段之一。本文将介绍几种常见的索引优化技巧,以及详细的代码示例。一、了...
    99+
    2023-10-21
    MySQL PHP 索引优化
  • oracle大数据量查询优化的方法是什么
    有几种方法可以优化Oracle中大数据量查询的性能:1. 创建合适的索引:根据查询条件和频繁使用的列,创建适当的索引可以大大提高查询...
    99+
    2023-09-26
    oracle
  • 30个mysql千万级大数据SQL查询优化技巧详解
    1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引。 2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导...
    99+
    2024-04-02
  • Oracle中如何处理大量数据的查询优化
    在Oracle中处理大量数据的查询优化可以通过以下几种方法来实现: 创建索引:在数据库表中创建索引可以加快数据查询的速度。可以根...
    99+
    2024-04-09
    Oracle
  • 数据库查询优化之子查询优化的示例分析
    这篇文章将为大家详细讲解有关数据库查询优化之子查询优化的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。1. 案例取所有不为掌门人的员工,按年龄分组!selec&#...
    99+
    2024-04-02
  • MySQL百万数据深度分页优化思路解析
    目录业务场景瓶颈再现问题分析回表覆盖索引IOLIMTI 2000,10 ?问题总结解决方案优化前后性能对比业务场景 一般在项目开发中会有很多的统计数据需要进行上报分析,一般在分析过后会在后台展示出来给运营和产品进行分页查...
    99+
    2023-05-12
    MySQL数据分页优化 MySQL分页优化百万级数据
  • MariaDB中如何优化大型查询和数据分析
    在MariaDB中优化大型查询和数据分析的方法有很多,以下是一些建议: 索引优化:为经常被查询的字段添加索引,以加快查询速度。尽...
    99+
    2024-04-09
    MariaDB
  • MySQL数据量大如何优化
    优化MySQL的方法主要有以下几种:1. 确保适当的索引:索引可以大大加快查询速度,因此在数据库设计时要确保为常用的查询字段添加适当...
    99+
    2023-10-08
    MySQL
  • Mysql查询优化之IN子查询优化方法详解
    目录物化表物化表转连接总结物化表 首先提出一个不相关的IN子查询 SELECT * FROM s1 WHERE key1 IN (SELECT commo...
    99+
    2023-02-09
    mysql in子查询优化 mysql in语句优化 mysql查询效率优化
  • 如何理解MySQL数据链表查询思路
    如何理解MySQL数据链表查询思路,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。  我们在网站开发中,涉及MySQL数据库查询时,常常需要...
    99+
    2024-04-02
  • MySQL优化 - 性能分析与查询优化
    MySQL优化 - 性能分析与查询优化    优化应贯穿整个产品开发周期中,比如编写复杂SQL时查看执行计划,安装MySQL服务器时尽量合理配置(见过太多完全使用默认配置安装的情况),根...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作