精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

查詢飛起!SpringBoot樹形結構從3秒飆到30毫秒的“神級加速”實錄

開發 前端
從遞歸查詢到高性能樹構建,我們完成了 從 O(n2) 到 O(n) 的質變。? 這一優化讓首頁分類樹的響應時間從 3 秒降到 30 毫秒,真正達到了用戶“無感知”的速度,系統穩定性和可維護性也得到極大提升。

在實際業務中,分類樹(Category Tree)往往是電商、內容管理、權限體系等系統的核心數據結構。隨著業務規模不斷擴張,原本毫無壓力的樹形查詢,突然變成了系統性能的瓶頸。

我所在的項目在首頁加載分類樹時,最初需要 3–5 秒 才能渲染完成,用戶大量投訴“卡頓、慢”,運維監控顯示 高峰期數據庫連接池被耗盡,甚至引發系統崩潰。開發團隊雖然嘗試過各種優化,但基本都屬于“打補丁”,沒能解決根本問題。

最終我們通過一次性查詢 + 高效內存構建樹的方式,將性能從 3 秒直接壓縮到 30 毫秒,實現了 100 倍提速。本文將完整還原這個過程,幫助你在遇到類似問題時快速找到正確的解決方案。

性能瓶頸:遞歸查詢的災難

傳統做法通常是遞歸調用 getChildren(),每次訪問數據庫查詢子節點,看似簡潔,實則暗藏殺機。

public List<Category> getCategoryTree() {
    List<Category> roots = categoryMapper.getRootCategories(); // 1次查詢
    for (Category root : roots) {
        loadChildren(root); // 每個節點觸發遞歸查詢
    }
    return roots;
}


private void loadChildren(Category parent) {
    List<Category> children = categoryMapper.getByParentId(parent.getId()); // N次查詢
    parent.setChildren(children);
    for (Category child : children) {
        loadChildren(child);
    }
}

問題分析:

  • 1 萬節點 = 1 萬次 SQL
  • 單次查詢平均 2ms → 總耗時 20 秒
  • 數據庫連接池被瞬間榨干
  • 內存中反復創建對象,GC 壓力暴增

結果就是:首頁分類樹幾乎不可用

性能測試對比

我們對比了不同規模下的執行耗時:

節點數

遞歸查詢方案

優化后方案

提升倍數

1,000

800ms

15ms

53x

5,000

2.8s

25ms

112x

10,000

5.2s

30ms

173x

50,000

超時

45ms

1000x+

根本解決思路:一次查詢 + O(n) 算法

核心理念

  • 數據庫只查一次 → 獲取所有節點
  • HashMap 建索引 → O(1) 查找父子關系
  • 單次遍歷構建樹 → O(n) 時間復雜度
  • 結果緩存 → 避免重復構建

數據庫表設計(鄰接表 + level 字段)

CREATE TABLE category (
    id BIGINT PRIMARY KEY,
    name VARCHAR(100) NOT NULL,
    parent_id BIGINT,
    level INT NOT NULL DEFAULT 0,
    sort_order INT DEFAULT 0,
    status TINYINT DEFAULT 1,
    create_time DATETIME,
    update_time DATETIME,
    INDEX idx_parent_id (parent_id),
    INDEX idx_level (level),
    INDEX idx_status (status)
);

設計要點:

  • level:支持批量層級查詢和排序優化
  • (parent_id, sort_order) 復合索引 → 高效排序
  • status:軟刪除、狀態過濾

復雜度對比

維度

遞歸方案

優化后方案

提升

時間復雜度

O(n2)

O(n)

線性提升

空間復雜度

O(h)(遞歸棧深度)

O(n)(HashMap)

更可控

數據庫查詢

O(n)

O(1)

極大減少

網絡 I/O

n 次

1 次

n 倍減少

優化后的算法實現

通用樹構建器

@Component
public class TreeBuilder {


    public <T extends TreeNode<T>> List<T> buildTree(List<T> nodes, Object rootValue) {
        if (CollectionUtils.isEmpty(nodes)) {
            return new ArrayList<>();
        }


        // 1. 建立快速索引 O(n)
        Map<Object, T> nodeMap = nodes.stream()
            .collect(Collectors.toMap(TreeNode::getId, node -> node));


        List<T> rootNodes = new ArrayList<>();


        // 2. 單次遍歷構建父子關系 O(n)
        for (T node : nodes) {
            Object parentId = node.getParentId();
            if (Objects.equals(parentId, rootValue)) {
                rootNodes.add(node);
            } else {
                T parent = nodeMap.get(parentId);
                if (parent != null) {
                    parent.addChild(node);
                }
            }
        }


        // 3. 可選:遞歸排序 O(n log n)
        sortTree(rootNodes);


        return rootNodes;
    }


    private <T extends TreeNode<T>> void sortTree(List<T> nodes) {
        if (CollectionUtils.isEmpty(nodes)) return;
        nodes.sort(Comparator.comparing(TreeNode::getSortOrder,
            Comparator.nullsLast(Comparator.naturalOrder())));
        for (T node : nodes) {
            if (node.hasChildren()) sortTree(node.getChildren());
        }
    }
}
樹節點基類
public interface TreeNode<T> {
    Object getId();
    Object getParentId();
    Integer getSortOrder();
    List<T> getChildren();
    void setChildren(List<T> children);


    default void addChild(T child) {
        if (getChildren() == null) setChildren(new ArrayList<>());
        getChildren().add(child);
    }


    default boolean hasChildren() {
        return getChildren() != null && !getChildren().isEmpty();
    }
}

業務實現

實體類

package com.icoderoad.module.category;


import com.icoderoad.core.tree.TreeNode;
import lombok.Data;


import java.util.List;


@Data
public class Category implements TreeNode<Category> {
    private Long id;
    private String name;
    private Long parentId;
    private Integer level;
    private Integer sortOrder;
    private Integer status;
    private List<Category> children;


    @Override
    public Object getId() {
        return id;
    }


    @Override
    public Object getParentId() {
        return parentId;
    }


    @Override
    public Integer getSortOrder() {
        return sortOrder;
    }
}

Mapper

package com.icoderoad.module.category;


import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;


import java.util.List;


@Mapper
public interface CategoryMapper {


    @Select("SELECT id, name, parent_id AS parentId, level, sort_order AS sortOrder, status " +
            "FROM category WHERE status = 1 ORDER BY sort_order ASC")
    List<Category> findAllActive();
}

Service 接口

package com.icoderoad.module.category;


import java.util.List;


public interface CategoryService {
    List<Category> getCategoryTree();
}

 Service 實現類

package com.icoderoad.module.category;


import com.icoderoad.core.tree.TreeBuilder;
import lombok.RequiredArgsConstructor;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;


import java.util.List;


@Service
@RequiredArgsConstructor
public class CategoryServiceImpl implements CategoryService {


    private final CategoryMapper categoryMapper;
    private final TreeBuilder treeBuilder;


    @Override
    @Cacheable(value = "categoryTree", key = "'all'")
    public List<Category> getCategoryTree() {
        List<Category> all = categoryMapper.findAllActive();
        return treeBuilder.buildTree(all, 0L); // 假設根節點 parentId=0
    }
}

Controller

package com.icoderoad.module.category;


import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;


import java.util.List;


@RestController
@RequiredArgsConstructor
public class CategoryController {


    private final CategoryService categoryService;


    @GetMapping("/categories/tree")
    public List<Category> getCategoryTree() {
        return categoryService.getCategoryTree();
    }
}

緩存優化

我們采用 多級緩存(Caffeine + Redis),既能保證高并發下的讀性能,又能兼顧分布式環境中的一致性。

  • L1:Caffeine(本地內存,10 分鐘過期)
  • L2:Redis(分布式,2 小時過期)
  • 啟動時預熱,定時刷新,避免冷啟動雪崩

監控與保障

  • 使用 Micrometer 統計樹構建耗時
  • 結合 Prometheus + Grafana 做性能監控
  • 高峰期壓力測試驗證可承載 5 萬節點,毫秒級響應

結論

從遞歸查詢到高性能樹構建,我們完成了 從 O(n2) 到 O(n) 的質變。 這一優化讓首頁分類樹的響應時間從 3 秒降到 30 毫秒,真正達到了用戶“無感知”的速度,系統穩定性和可維護性也得到極大提升。

如果你正面臨類似的 N+1 查詢困境,建議優先考慮:

  1. 一次查詢 + 內存建樹,徹底消滅遞歸 SQL
  2. 合理索引 + Level 字段,讓樹形結構查詢更高效
  3. 多級緩存策略,提升并發訪問下的可用性
  4. 監控與預警,持續觀察系統性能變化

性能優化沒有銀彈,但思路正確,就能實現百倍提升。

責任編輯:武曉燕 來源: 路條編程
相關推薦

2025-06-27 09:05:47

2013-11-11 11:17:45

AngularJS性能優化

2025-06-25 09:30:14

2024-11-08 15:08:17

2021-04-27 06:20:25

MySQL集群優化

2017-12-25 11:15:06

JavaArray數組

2022-06-15 11:27:15

開源代碼項目

2019-08-21 14:35:18

壓縮文件優化過程Java

2024-04-10 08:00:00

PostgresNoSQL

2020-11-12 18:51:43

Java編程語言

2025-09-15 03:00:00

2012-03-11 15:27:57

微軟

2025-03-24 08:51:16

2017-05-31 13:58:05

戴爾宕機服務器

2021-05-19 15:35:19

數據庫工具技術

2015-03-20 10:01:50

Android StuGradle

2019-01-30 09:34:56

ElasticSearLogstashKibana

2018-12-21 10:39:31

華為

2024-11-01 12:10:57

2017-08-11 14:28:02

58同城推薦系統
點贊
收藏

51CTO技術棧公眾號

久久都是精品| 激情小视频网站| 91女神在线观看| www.av导航| 日本精品黄色| 亚洲综合999| 国产丝袜精品第一页| 亚洲国产精品视频一区| 精品无码av在线| 精品九九久久| 久久奇米777| 欧美大片免费看| 五月婷婷狠狠操| 神马精品久久| 国产欧美自拍一区| 中文字幕在线不卡视频| 国产极品jizzhd欧美| 欧美深性狂猛ⅹxxx深喉| 中文在线观看免费| 国产综合久久久久久久久久久久| 国产偷亚洲偷欧美偷精品| 第四色婷婷基地| 多野结衣av一区| 不卡的av在线| 97视频色精品| 精品中文字幕在线播放| 免费视频成人| 欧美视频一区二区三区…| 国产精品视频一区二区三区经| 久久久久亚洲AV成人| 国产 日韩 欧美| 亚洲精品中文字幕在线观看| 69堂成人精品视频免费| 欧美又粗又大又长| 欧美色图在线播放| 精品伊人久久97| 妖精视频在线观看| 蜜桃传媒在线观看免费进入| 成人动漫在线一区| 91亚洲va在线va天堂va国| 国产精品 欧美激情| 日韩中文字幕在线一区| 亚洲大片免费看| 久久精品ww人人做人人爽| 国产午夜无码视频在线观看| 日韩av密桃| 日韩欧美久久一区| 国产精品沙发午睡系列| 国产在线91| 精品一区二区三区日韩| 欧美高清电影在线看| 天天爽天天爽天天爽| 91成人短视频| 91久久精品日日躁夜夜躁欧美| 亚洲mv在线看| www.日韩高清| 国产精品一级在线| 日韩免费观看高清| 成人在线观看高清| 亚洲精品无吗| 欧美一区二区三区在线| 777精品久无码人妻蜜桃| 成人高清免费观看mv| 国产在线麻豆精品观看| 成人欧美一区二区三区黑人孕妇| 在线观看成人毛片| 欧美先锋影音| 亚洲视频电影图片偷拍一区| 国产精品久久久久久久99| 九色porny自拍视频在线播放| 国产欧美日韩三级| 国产免费久久av| 精品无码一区二区三区电影桃花 | 国产欧美一区二区视频| 国产精品久免费的黄网站| 日韩理论电影| 久久精品91久久久久久再现| 在线免费播放av| 国产精品免费大片| 精品久久久久久久久久久久久久久久久 | 天天爽夜夜爽一区二区三区 | 欧美大尺度激情区在线播放| 亚洲欧美日本一区| 韩国精品主播一区二区在线观看 | 国产一区一区| 精品国精品国产| 精品无码人妻一区| 久久伊人影院| 欧美唯美清纯偷拍| 男人添女人下部高潮视频在观看| 免费日本一区二区三区视频| 久久久久久一二三区| 国产伦精品一区二区三区照片91 | 网站一区二区| 亚洲欧美国产日韩天堂区| 一级黄色免费毛片| 日本一区二区中文字幕| 在线观看视频一区二区| 91成人在线观看喷潮教学| 亚洲不卡系列| 色系网站成人免费| 国产午夜大地久久| 成人福利一区二区| 欧美性大战久久久| 91精品人妻一区二区三区蜜桃2 | 欧美尤物美女在线| 亚洲6080在线| 中文字幕人妻熟女人妻洋洋| 免费观看在线黄色网| 亚洲成人免费视| 污污的网站免费| 国产亚洲人成a在线v网站| 欧美成人一级视频| 久久精品色妇熟妇丰满人妻| 精品一区二区三区在线| 亚洲视频在线播放| 久热这里只有精品在线| 久久99精品国产麻豆婷婷洗澡| 精品欧美一区二区精品久久| 污污视频在线观看网站| 成人v精品蜜桃久久一区| 亚洲v国产v在线观看| 午夜影院在线观看国产主播| 欧美性猛交xxxx黑人猛交| 992kp免费看片| 成人午夜av| 国产va免费精品高清在线观看| a天堂在线观看视频| 国产成人丝袜美腿| 国产精品视频在线免费观看 | 免费av网址在线| 最新日韩三级| 欧美亚洲动漫另类| 中文字幕av观看| 亚洲特级毛片| 欧美在线一级视频| 国产又粗又猛又爽又| av午夜精品一区二区三区| 美日韩免费视频| 国产福利片在线| 亚洲视频一区二区在线| 国产一级爱c视频| 欧美电影免费观看高清完整| 亚洲国产日韩欧美在线图片 | 136福利视频导航| 国产一区二区导航在线播放| 先锋在线资源一区二区三区| 户外露出一区二区三区| 亚洲香蕉在线观看| 日韩三级在线观看视频| 久久99久久99| 日日噜噜噜夜夜爽爽| 超碰在线97国产| 在线观看网站黄不卡| 亚洲女优在线观看| 欧美3p在线观看| 国模精品系列视频| 中文字幕免费高清在线观看| 国产成人av网站| 日本一区二区三区www| 国精产品一区| 日韩欧美在线视频免费观看| 国产精品日日摸夜夜爽| 精品一区二区三| 国产精品流白浆视频| 亚洲乱色熟女一区二区三区| 国产激情一区二区三区四区| 久久久国内精品| 成人黄色毛片| 按摩亚洲人久久| 欧美三级午夜理伦| 韩日欧美一区二区三区| 久久久久久精| 亚洲成av在线| 久久伊人91精品综合网站| 欧美性猛交bbbbb精品| 久久精品一区二区三区av| 亚洲欧洲日本精品| 欧美aa国产视频| 国产精品美女www爽爽爽视频| av在线女优影院| 日韩一区二区精品葵司在线| 欧美亚洲色综久久精品国产| 亚洲裸体俱乐部裸体舞表演av| 国产在线精品播放| 国产资源在线观看| 欧美妇女性影城| 精品人妻中文无码av在线| 狠狠色综合播放一区二区| 国产精品入口芒果| 狠狠操综合网| 不卡视频一区二区三区| av毛片在线播放| 亚洲乱码国产乱码精品精天堂| 又骚又黄的视频| 国产午夜亚洲精品理论片色戒| 黄色一级视频片| 欧美日韩在线播放视频| 国产aⅴ精品一区二区三区黄| 成人在线观看免费网站| 欧美日韩国产一级二级| 中文字幕第4页| 免费日韩av片| 久久精品aaaaaa毛片| 91精品一区| 久热国产精品视频| 久久电影中文字幕| 日韩三级免费观看| 欧美成人一区二区视频| 中文字幕免费观看一区| 性猛交ⅹ×××乱大交| 亚洲激情不卡| 天堂av在线中文| 999国产精品一区| 97久久精品在线| 免费观看成人高潮| 中文字幕精品国产| 一级视频在线播放| 欧美性生交xxxxx久久久| 免费日韩在线视频| 成人性生交大片免费看中文| 国产二区视频在线| 91精品蜜臀一区二区三区在线| 91在线视频九色| 成人短视频在线| 国产一区二区三区三区在线观看| 日韩有码第一页| 日韩欧美国产一区二区| 久久这里只有精品国产| 椎名由奈av一区二区三区| 亚洲美女精品视频| 久久99国产精品免费网站| 日本久久久久久久久久久久| 久久99伊人| 成年人观看网站| 国产精品一区亚洲| 亚洲欧美影院| 精品国产1区| 欧美日韩一区二| 国产精品一区二区免费福利视频 | 欧美激情喷水| 欧美与黑人午夜性猛交久久久| 日韩黄色影片| 欧美亚洲动漫另类| 自拍偷拍18p| 中文字幕一区视频| www.99re6| youjizz久久| 国产精品亚洲一区二区无码| 国产精品资源在线看| 污视频在线观看免费网站| 精品亚洲国产成人av制服丝袜| 超碰在线播放91| 蜜臀久久99精品久久久久宅男| 一本二本三本亚洲码| 999精品一区| 中国一级大黄大黄大色毛片| 国内精品麻豆美女在线播放视频| 99久久综合狠狠综合久久止| 亚洲一区 二区| 国精产品99永久一区一区| 欧美1区二区| 国产97在线播放| 欧美色片在线观看| 国产区精品视频| 蜜桃精品视频| 久久99精品久久久久久水蜜桃| 涩爱av在线播放一区二区| 欧美精品久久一区| 国产视频一区二区三区四区五区| 亚洲第一福利视频在线| 日韩成年人视频| 国产精品福利一区二区三区| 卡通动漫亚洲综合| 亚洲电影第三页| 最新中文字幕一区| 欧美影院精品一区| 中文字幕网站在线观看| 国产欧美一二三区| 午夜精品福利在线视频| 一区二区三区加勒比av| 香蕉视频一区二区| 91久久精品一区二区三| 国产黄色一区二区| 日韩av在线免费观看| 国产一区二区在线视频聊天| 日韩视频国产视频| 青青草视频在线免费观看| 久久精品电影网站| 国模私拍一区二区国模曼安| 国产精品久久久久久搜索| 亚洲一二av| 亚洲三区视频| 国产成人精品免费视| 永久免费在线看片视频| 久久成人一区| 亚洲免费观看在线| 中文字幕av资源一区| 日韩av男人天堂| 欧美日韩1234| 欧美伦理影视网| 日韩国产精品亚洲а∨天堂免| 91福利在线视频| 中文亚洲视频在线| www.色在线| 91影院在线免费观看视频| 国产一区二区三区不卡视频网站| 在线观看日韩片| 91tv精品福利国产在线观看| 日韩少妇内射免费播放18禁裸乳| 精品亚洲国产成人av制服丝袜| 熟女俱乐部一区二区视频在线| 26uuu精品一区二区三区四区在线| 99热超碰在线| 99久久777色| 91网站免费视频| 一区二区欧美国产| 在线观看黄色网| 亚洲日本成人网| 蜜桃视频在线观看免费视频| 亚洲最大福利网站| 日韩精品诱惑一区?区三区| 无码人妻丰满熟妇区毛片18| 成人免费高清在线| 麻豆changesxxx国产| 555www色欧美视频| 国产露脸国语对白在线| 日韩久久精品一区| 永久免费在线观看视频| 久久av.com| 欧美啪啪网站| 日韩在线三区| 亚洲色图网站| 日本a在线免费观看| 国产精品一区一区三区| 国产精品国产三级国产传播| 欧美视频你懂的| 97人妻一区二区精品免费视频| 国产亚洲激情视频在线| 另类专区亚洲| 成人福利视频网| 欧美成免费一区二区视频| 538任你躁在线精品免费| 日本一区二区三区四区在线视频| 中文字幕在线播| 亚洲欧美日韩精品| 三上悠亚一区二区| 欧美日韩最好看的视频| 日韩中文欧美在线| 自拍一级黄色片| 亚洲欧美电影一区二区| 国产高清精品软件丝瓜软件| 欧美激情视频免费观看| 国产精品白丝av嫩草影院| 国产综合中文字幕| 久久综合久久鬼色中文字| 青青视频在线免费观看| 中国china体内裑精亚洲片| 国产精品亚洲成在人线| 成年人三级视频| 成人免费毛片片v| 国产成人综合欧美精品久久| 亚洲天堂成人在线| 日韩成人在线电影| 成年丰满熟妇午夜免费视频 | 91久久免费观看| 欧洲不卡av| 国产精品入口免费| 久热精品在线| 久草免费资源站| 欧美日韩亚洲91| 亚洲精品喷潮一区二区三区| 久久久久久12| 成人97精品毛片免费看| 人妻无码一区二区三区四区| 99久久国产综合色|国产精品| 久久久久久久久久成人| 久久精品久久久久久国产 免费| 日韩免费高清视频网站| 国产91美女视频| 国产精品福利av| 天天干天天干天天干| 欧美另类暴力丝袜| 在线观看亚洲精品福利片| www.欧美黄色| 国产日韩精品一区二区三区 | 亚洲护士老师的毛茸茸最新章节| 久久久一本精品| 国产成人生活片| 久久久午夜电影| 精品久久久久成人码免费动漫| 538国产精品一区二区在线| 国产精品88久久久久久| 一级特黄性色生活片| 亚洲激情第一区| 午夜精品小视频| 国产97在线观看| 亚洲精选久久| 丝袜美腿小色网| 亚洲深夜福利视频|