最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Mysql大數(shù)據(jù)量查詢優(yōu)化思路詳析

 更新時間:2022年01月26日 11:03:02   作者:老司機(jī)張師傅?  
這篇文章主要介紹了Mysql大數(shù)據(jù)量查詢優(yōu)化思路,Mysql大表查詢優(yōu)化,理論上千萬級別以下的數(shù)據(jù)量Mysql單表查詢性能處理都是可以的。下文我們就來看看具體得思路解析

項(xiàng)目場景:

Mysql大表查詢優(yōu)化,理論上千萬級別以下的數(shù)據(jù)量Mysql單表查詢性能處理都是可以的。

問題描述:

在我們線上環(huán)境中,出現(xiàn)了mysql幾千萬級別的日志查詢、幾百萬級別的黑名單庫查詢分頁查詢及條件查詢都慢的問題,針對Mysql表優(yōu)化做了一些優(yōu)化處理。

原因分析:
首先說一下日志查詢,在Mysql中如果索引加的比較合適,走索引情況下千萬級別查詢不會超過一秒,Mysql查詢的速度和檢索的數(shù)據(jù)條數(shù)有關(guān)。在Mybatis中,分頁查詢是先執(zhí)行Count記錄總數(shù),再執(zhí)行l(wèi)imit a,b 的方式來進(jìn)行的,而Mysql的Count計(jì)數(shù)方式是將所有的數(shù)據(jù)過濾一遍進(jìn)行累加,因此當(dāng)日志表數(shù)據(jù)過千萬時,統(tǒng)計(jì)一次就是十幾秒鐘的時間(這里是服務(wù)器環(huán)境,本地情況下甚至是幾分鐘)。
limit a,b的方式也一樣,Mysql查詢時會先一條一條數(shù)到第a條,然后向后再數(shù)b條作為查詢結(jié)果,因此當(dāng)起始行數(shù)越來越大時查詢同樣會變得很慢,也就是當(dāng)你點(diǎn)第一頁時可能一下就查出來了,當(dāng)你點(diǎn)最后一頁的時候可能幾十秒才能查出來。
黑名單庫查詢優(yōu)化同理,也是需要通過條件優(yōu)化。
在進(jìn)行大批量數(shù)據(jù)落庫時,使用的Mybatis批量插入,發(fā)現(xiàn)當(dāng)批次數(shù)據(jù)超過3000時速度會急劇變慢,這是一個Mybatis娘胎里自帶的問題,也需要進(jìn)行解決。

解決方案:

這里只簡單說明優(yōu)化的幾個方向。

1. 千萬級別日志查詢的優(yōu)化

  1. 首先說下日志查詢,重點(diǎn)是優(yōu)化無條件是分頁查詢,在無條件時,不使用MyBatis的分頁插件,而是自己手寫一個分頁查詢,由于MySql的count耗時過長,我們先優(yōu)化他。
  2. 優(yōu)化Count:日志表的數(shù)據(jù)只增,不會出現(xiàn)中間某條刪除,所以他的數(shù)據(jù)可以理解成是連續(xù)的,我們可以在內(nèi)存中直接進(jìn)行計(jì)數(shù),記錄count總數(shù),或者給表添加一個自增的ID字段,直接select max(id)就是總數(shù)量,這樣count查詢的效率會提升到毫秒級別。
  3. 自定義分頁查詢:分頁查詢中使用優(yōu)化后的count記錄總數(shù),然后使用(page - 1)* pageSize + 1公式計(jì)算出當(dāng)前頁的最小ID,然后將limit a,b 的Sql語句改為where ID > 最小ID limit b的方式,這樣查詢就會走索引先將小于最小ID的數(shù)據(jù)過濾掉,再進(jìn)行查詢,經(jīng)過第二步和第三步的優(yōu)化后分頁查詢效率縮短到了一秒內(nèi),并且不會隨著頁數(shù)的增長而變慢。
  4. 條件查詢:條件查詢只能設(shè)置合適的索引,另外慎用like '%條件%‘的方式進(jìn)行匹配查詢,這樣會導(dǎo)致索引失效全局檢索,模糊查詢盡量使用like '條件%' 的方式進(jìn)行最左匹配,也可以使用explain+sql語句 的方式來查看sql語句的執(zhí)行效率,是否走了所有啥的來針對性的優(yōu)化,加好合適的索引、優(yōu)化查詢語句后通常一千萬以內(nèi)的數(shù)據(jù)查詢效率會在3秒內(nèi)。

粘出自定義分頁查詢結(jié)果封裝:

?// 手動count
? ? ? ? ? ? ? ? Integer total = logPushService.queryBackCount(resMap);//查詢數(shù)量
? ? ? ? ? ? ? ? // 手動查詢結(jié)果
? ? ? ? ? ? ? ? List<InterceptInfo> ls = logPushService.queryBackByPage(resMap);
? ? ? ? ? ? ? ? PageInfo pageInfo = new PageInfo();
? ? ? ? ? ? ? ? pageInfo.setTotal(total);
? ? ? ? ? ? ? ? pageInfo.setPageSize(limit);
? ? ? ? ? ? ? ? pageInfo.setList(ls);
? ? ? ? ? ? ? ? pageInfo.setPageNum(pn);

2. 幾百萬黑名單庫的查詢優(yōu)化

  • 黑名單庫查詢優(yōu)化只能通過加合適的索引和優(yōu)化SQL語句來優(yōu)化,百萬級別數(shù)據(jù)松松的在Mysql和Mybatis的承受范圍內(nèi),這里是由于黑名單庫不是使用遞增的,有可能會增加也有可能會刪除,所以只能使用優(yōu)化索引和SQL的方式進(jìn)行優(yōu)化。
  • 另外,Mybatis框架提供了重寫分頁查詢count統(tǒng)計(jì)語句的方法,只需要將count語句命名為查詢方法_COUNT即可,例如分頁查詢的語句方法是query,那么重寫的統(tǒng)計(jì)方法即為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批量插入語句中的類集合大小不能超過五千,三千是最佳,這是測試出來的結(jié)果,考慮到的原因是Mybatis會將類做反射,這個太影響效率,因此批量插入時要注意這個,如果你能夠三千三千的批量處理就限制一下,不要讓每批數(shù)據(jù)超過3000,數(shù)據(jù)量過大時也可以使用異步非阻塞的方式來插入。
異步非阻塞代碼(只是步驟樣例,存在代碼缺失):

? ? // 執(zhí)行全量HMD導(dǎo)入任務(wù)的線程池
? ? public final static ExecutorService importHasPool = Executors.newFixedThreadPool(10);
? ? public final static CompletionService<DoExcelResult> importHasPoolService = new ExecutorCompletionService<>(importHasPool);
? ??
? ?public synchronized DoExcelResult example() {
? ? ? ? ? ? // 開始執(zhí)行導(dǎo)入
? ? ? ? ? ? // 寫到這里面方法最后會自動關(guān)閉
? ? ? ? ? ? long startTime = System.currentTimeMillis();
? ? ? ? ? ? // 定義一個集合,記錄Callable的執(zhí)行結(jié)果,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是實(shí)現(xiàn)了Callable接口的實(shí)現(xiàn)類,Callable是帶返回值的Runable
? ? ? ? ? ? ? ? ? ? Future submit = SysThreadPoolCenter.importHasPoolService.submit(new BlackInfoHasImportlCallable(list1, blacklistInfoMapper));
? ? ? ? ? ? ? ? ? ? futures.add(submit);
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? ? ??
? ? ? ? ? ? // 等待執(zhí)行結(jié)果
? ? ? ? ? ? for (Future<DoExcelResult> future : futures) {
? ? ? ? ? ? ? ? try {
? ? ? ? ? ? ? ? // 2. futrue.get時會獲取返回值,線程沒執(zhí)行完畢就等待等待執(zhí)行結(jié)果
? ? ? ? ? ? ? ? ? ? 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);
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? ? ? // 循環(huán)結(jié)束代表所有線程執(zhí)行完畢
? ? ? ? ? ? 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);
? ? ? ? }

如果你數(shù)據(jù)庫用的不是mysql,而是CK或者其他的大數(shù)據(jù)處理數(shù)據(jù)庫,批量插入可能要求每秒幾萬條幾十萬條,這時就不再適合使用Myabtis框架了,建議使用JDBC連接的方式,自己寫代碼拼接sql語句,再使用jdbc連接執(zhí)行(使用線程池),效率上會快很多。

到此這篇關(guān)于Mysql大數(shù)據(jù)量查詢優(yōu)化思路詳析的文章就介紹到這了,更多相關(guān)Mysql大數(shù)據(jù)量查詢優(yōu)化內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 根據(jù)mysql慢日志監(jiān)控SQL語句執(zhí)行效率

    根據(jù)mysql慢日志監(jiān)控SQL語句執(zhí)行效率

    根據(jù)mysql慢日志監(jiān)控SQL語句執(zhí)行效率 啟用MySQL的log-slow-queries(慢查詢記錄)。
    2012-11-11
  • 詳解MySQL如何實(shí)現(xiàn)數(shù)據(jù)批量更新

    詳解MySQL如何實(shí)現(xiàn)數(shù)據(jù)批量更新

    最近需要批量更新大量數(shù)據(jù),習(xí)慣了寫sql,所以還是用sql來實(shí)現(xiàn),下面這篇文章主要給大家總結(jié)介紹了關(guān)于MySQL批量更新的方式,需要的朋友可以參考下
    2023-10-10
  • mysql 判斷記錄是否存在方法比較

    mysql 判斷記錄是否存在方法比較

    把數(shù)據(jù)寫入到數(shù)據(jù)庫的時,常常會碰到先要檢測要插入的記錄是否存在,然后決定是否要寫入。
    2011-08-08
  • MySQL批量導(dǎo)入Excel數(shù)據(jù)(超詳細(xì))

    MySQL批量導(dǎo)入Excel數(shù)據(jù)(超詳細(xì))

    這篇文章主要介紹了MySQL批量導(dǎo)入Excel數(shù)據(jù)(超詳細(xì)),文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價值,感興趣的小伙伴可以參考一下,希望對你的學(xué)習(xí)有所幫助
    2022-08-08
  • Mysql服務(wù)器的啟動與停止(二)

    Mysql服務(wù)器的啟動與停止(二)

    Mysql服務(wù)器的啟動與停止(二)...
    2006-11-11
  • MySql總彈出mySqlInstallerConsole窗口的解決方法

    MySql總彈出mySqlInstallerConsole窗口的解決方法

    這篇文章主要介紹了MySql總彈出mySqlInstallerConsole窗口的解決方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-09-09
  • MySQL 5.7.17 免安裝版本的安裝配置

    MySQL 5.7.17 免安裝版本的安裝配置

    這篇文章主要為大家詳細(xì)介紹了MySQL 5.7.17 免安裝版本的安裝配置教程,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-11-11
  • 關(guān)于SQL建表語句使用詳解

    關(guān)于SQL建表語句使用詳解

    在SQL數(shù)據(jù)庫設(shè)計(jì)中,創(chuàng)建表是基本操作,涉及定義表結(jié)構(gòu),包括列名、數(shù)據(jù)類型和約束等,本文詳細(xì)介紹建表語句,通過示例幫助理解,常見數(shù)據(jù)類型包括整數(shù)、浮點(diǎn)數(shù)、字符串、日期時間等,約束確保數(shù)據(jù)完整性,包括主鍵、唯一、非空、默認(rèn)值、外鍵和檢查約束
    2024-10-10
  • MySQL中sql_mode模式的使用

    MySQL中sql_mode模式的使用

    mysql為了支持在不同的環(huán)境下運(yùn)行,允許我們給它設(shè)置不同的運(yùn)行模式,本文主要介紹了MySQL中sql_mode模式的使用,具有一定的參考價值,感興趣的可以了解一下
    2024-08-08
  • 一文詳解MySQL不同隔離級別都使用什么鎖

    一文詳解MySQL不同隔離級別都使用什么鎖

    這篇文章主要為大家詳細(xì)介紹了在MySQL中不同隔離級別都會使用什么鎖,文中的示例代碼講解詳細(xì),對我們學(xué)習(xí)MySQL有一定幫助,需要的可以參考一下
    2022-09-09

最新評論

常山县| 二连浩特市| 来宾市| 徐水县| 绥德县| 黄冈市| 花莲市| 卢龙县| 茂名市| 唐山市| 大冶市| 辽源市| 闵行区| 东莞市| 崇阳县| 蓬安县| 沭阳县| 德惠市| 黄大仙区| 遵义市| 五大连池市| 乳山市| 城固县| 枣庄市| 广西| 凤阳县| 沁源县| 河北区| 兴山县| 武宣县| 伊通| 红原县| 绥江县| 和静县| 板桥市| 开远市| 英德市| 温宿县| 大姚县| 南部县| 白银市|