亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

SpringBoot使用索引來優(yōu)化SQL查詢的詳細(xì)步驟

 更新時(shí)間:2025年05月21日 10:44:21   作者:冰糖心書房  
在 Spring Boot 項(xiàng)目中使用索引來優(yōu)化 SQL 查詢是提升數(shù)據(jù)庫性能最常用的方法之一,下面是詳細(xì)的步驟和實(shí)踐指南,并通過代碼示例講解的非常詳細(xì),需要的朋友可以參考下

核心目標(biāo):讓數(shù)據(jù)庫能夠通過掃描索引(小范圍、有序的數(shù)據(jù)結(jié)構(gòu))快速定位到所需數(shù)據(jù)行,而不是掃描整個(gè)表(大數(shù)據(jù)量下非常慢)。

1. 理解索引的作用和場景

  • 加速查找: 主要優(yōu)化 WHERE 子句和 JOIN ON 條件的查找速度。
  • 加速排序: 優(yōu)化 ORDER BY 子句,避免文件排序 (filesort)。
  • 加速分組: 優(yōu)化 GROUP BY 子句,幫助快速找到相同分組。
  • 唯一性約束: UNIQUE 索引還能保證數(shù)據(jù)的唯一性。

2. 識別需要索引的查詢

在開始添加索引之前,先找出哪些查詢是性能瓶頸或者執(zhí)行頻率高。前面我們也介紹過,有興趣的小伙伴可以去看一下之前的文章,我們在回顧一下:

  • MySQL 慢查詢?nèi)罩?(Slow Query Log): 定位執(zhí)行時(shí)間長的 SQL。
  • APM 工具 (如 SkyWalking): 查看請求中耗時(shí)長的調(diào)用。
  • EXPLAIN 分析: 對懷疑有問題的 SQL 執(zhí)行 EXPLAIN,檢查執(zhí)行計(jì)劃。
  • 業(yè)務(wù)分析: 思考核心業(yè)務(wù)流程和高頻查詢場景。

重點(diǎn)關(guān)注涉及以下操作的查詢:

  • 過濾 (WHERE): findByEmail(String email)findAllByStatus(OrderStatus status)
  • 連接 (JOIN): 加載關(guān)聯(lián)實(shí)體,如查詢訂單及其用戶信息。
  • 排序 (ORDER BY): findAllByOrderByCreatedAtDesc()
  • 分組 (GROUP BY): 統(tǒng)計(jì)類查詢。

3. 掌握關(guān)鍵的索引類型

  • 單列索引 (Single-Column Index): 對單個(gè)列創(chuàng)建索引。適用于簡單的、基于該列的精確匹配或范圍查詢。
CREATE INDEX idx_users_email ON users (email);
  • 聯(lián)合索引 / 復(fù)合索引 (Composite / Multi-Column Index): 對多個(gè)列組合創(chuàng)建索引。極其重要,適用于涉及多個(gè)條件的 WHERE 子句或同時(shí)需要滿足 WHERE 和 ORDER BY / GROUP BY 的查詢。
-- 適用于 WHERE status = ? AND created_at > ?
CREATE INDEX idx_orders_status_created ON orders (status, created_at);
    • 最左前綴原則 (Leftmost Prefix Rule): 聯(lián)合索引 (a, b, c) 可以支持 WHERE a=?、WHERE a=? AND b=?WHERE a=? AND b=? AND c=? 的查詢,但通常不支持 WHERE b=? 或 WHERE a=? AND c=?。列的順序至關(guān)重要。
  • 覆蓋索引 (Covering Index): 如果一個(gè)索引包含了查詢所需的所有列(SELECTWHEREORDER BY 等),數(shù)據(jù)庫可以直接從索引返回結(jié)果,無需訪問數(shù)據(jù)表(回表),性能極高。
-- 查詢: SELECT user_id, status FROM orders WHERE order_date > ?
-- 覆蓋索引:
CREATE INDEX idx_orders_date_user_status ON orders (order_date, user_id, status);
  • 唯一索引 (Unique Index): 保證索引列的值唯一,通常用于業(yè)務(wù)上的唯一標(biāo)識(如用戶郵箱、手機(jī)號),同時(shí)也具備普通索引的查詢加速功能。
CREATE UNIQUE INDEX uk_users_email ON users (email);
  • 全文索引 (Full-Text Index): 用于對 TEXT 類型數(shù)據(jù)進(jìn)行關(guān)鍵詞搜索。

4. 在 Spring Boot 項(xiàng)目中創(chuàng)建和管理索引

下面我們將理論應(yīng)用到項(xiàng)目中實(shí)踐:

  • 錯(cuò)誤的方式(嚴(yán)禁用于生產(chǎn)環(huán)境?。?

    • 依賴 JPA/Hibernate 的 spring.jpa.hibernate.ddl-auto=update 或 create
    • 原因:
      • update 行為不可預(yù)測,可能丟失數(shù)據(jù)或產(chǎn)生意想不到的變更。
      • create 會刪除整個(gè)數(shù)據(jù)庫!
      • 無法進(jìn)行版本控制和團(tuán)隊(duì)協(xié)作。
      • 繞過了必要的 Code Review 和數(shù)據(jù)庫變更管理流程。
    • @Table(indexes = ...) 或 @Index 注解:這些注解主要是給 ddl-auto 用的,或者用于生成 DDL 腳本供其他工具使用,不應(yīng)該直接依賴它們在生產(chǎn)環(huán)境自動創(chuàng)建/更新索引
  • 正確的方式(生產(chǎn)環(huán)境標(biāo)準(zhǔn)):

    • 使用數(shù)據(jù)庫遷移工具 (Database Migration Tools): Flyway 或 Liquibase 是 Spring Boot 項(xiàng)目的最佳實(shí)踐和必備工具。
    • 工作流程:
      • 添加依賴: 在 pom.xml 或 build.gradle 中添加 Flyway 或 Liquibase 的 Spring Boot Starter 依賴。
<!-- Flyway Example -->
<dependency>
    <groupId>org.flywaydb</groupId>
    <artifactId>flyway-core</artifactId>
</dependency>
<dependency> <!-- If using MySQL -->
    <groupId>org.flywaydb</groupId>
    <artifactId>flyway-mysql</artifactId>
</dependency>

<!-- Liquibase Example -->
<dependency>
    <groupId>org.liquibase</groupId>
    <artifactId>liquibase-core</artifactId>
</dependency>
  1. 創(chuàng)建遷移腳本: 在 src/main/resources/db/migration (Flyway 默認(rèn)) 或指定的路徑 (Liquibase) 下創(chuàng)建 SQL 腳本。腳本命名需符合工具的版本規(guī)范(例如 Flyway: V1__Initial_schema.sqlV2__Add_index_on_users_email.sql)。
  2. 編寫 DDL: 在 SQL 腳本中使用標(biāo)準(zhǔn)的 CREATE INDEX 語句來定義索引。
-- V2__Add_index_on_users_email.sql
CREATE INDEX idx_users_email ON users (email);

-- V3__Add_composite_index_on_orders.sql
CREATE INDEX idx_orders_user_status ON orders (user_id, status);

-- V4__Add_unique_index_on_products.sql
CREATE UNIQUE INDEX uk_products_sku ON products (sku);
  1. 運(yùn)行應(yīng)用: Spring Boot 應(yīng)用啟動時(shí),F(xiàn)lyway/Liquibase 會自動檢測并按版本順序執(zhí)行新的遷移腳本,將索引變更應(yīng)用到數(shù)據(jù)庫。
  • 優(yōu)點(diǎn):
    • 版本控制: 索引的變更可以像代碼一樣納入 我們Git 管理倉庫中。
    • 可重復(fù): 在任何環(huán)境都能應(yīng)用相同的變更。
    • 自動化: 方便集成到 CI/CD 流程中。
    • 團(tuán)隊(duì)協(xié)作: 清晰的記錄了 Schema 的變更歷史。
    • 安全: 變更經(jīng)過了腳本和版本控制,減少了手動操作的失誤。

5. 針對常見 Spring Boot 查詢場景的索引策略示例

場景:通過唯一業(yè)務(wù)標(biāo)識查找實(shí)體 (如 User findByEmail(String email);)

  • SQL : SELECT * FROM users WHERE email = ?
  • 索引策略: 在 email 列上創(chuàng)建唯一索引 (Unique Index)。
CREATE UNIQUE INDEX uk_users_email ON users (email);

場景:根據(jù)狀態(tài)過濾并按時(shí)間排序的分頁列表 (如 Page<Order> findByStatusOrderByCreatedAtDesc(OrderStatus status, Pageable pageable);)

  • SQL : SELECT * FROM orders WHERE status = ? ORDER BY created_at DESC LIMIT ?, ?
  • 索引策略: 創(chuàng)建聯(lián)合索引,包含 status 和 created_at。status 是等值過濾,放前面;created_at 是排序,放后面。
CREATE INDEX idx_orders_status_created ON orders (status, created_at);
  • 進(jìn)階 (覆蓋索引): 如果只需要少數(shù)幾列(如 idorder_nostatuscreated_at),可以創(chuàng)建覆蓋索引以避免回表:
CREATE INDEX idx_orders_status_created_cover ON orders (status, created_at, id, order_no);

場景:加載關(guān)聯(lián)實(shí)體 (如獲取訂單及其用戶信息 Order order = orderRepository.findById(id); User user = order.getUser();)

  • JPA 可能生成 (取決于 FetchType):
    • 一次性 JOIN: SELECT ... FROM orders o LEFT JOIN users u ON o.user_id = u.id WHERE o.id = ?
    • N+1 (如果 LAZY Fetching 且后續(xù)訪問 user): 先查 order,再根據(jù) order.user_id 查 user。
  • 索引策略: 必須在外鍵列 (orders.user_id) 上創(chuàng)建索引。
CREATE INDEX idx_orders_user_id ON orders (user_id);
  • 這樣無論是 JOIN 查詢還是 N+1 中的第二次查詢,都能快速通過 user_id 找到對應(yīng)的訂單或用戶。
  • 場景:多條件過濾查詢 (如 List<Product> findByNameContainingAndCategoryAndPriceBetween(String name, String category, BigDecimal minPrice, BigDecimal maxPrice);)

    • SQL : SELECT * FROM products WHERE category = ? AND price BETWEEN ? AND ? AND name LIKE ? (注意 LIKE 的用法會影響索引效率)
    • 索引策略: 創(chuàng)建聯(lián)合索引。通常將等值查詢、選擇性高的列放在前面。范圍查詢 (BETWEEN) 和 LIKE 放后面。
      • 索引:(category, price, name)。這樣可以先用 category 過濾,再用 price 進(jìn)行范圍掃描。name 上的 LIKE 如果是 '%keyword%' 則此索引無效;如果是 'prefix%' 則可能有部分效果。
      • 如果 name 的查詢更頻繁或選擇性更高,也可以考慮 (name, category, price) 并使用前綴索引。需要根據(jù)實(shí)際情況分析。
CREATE INDEX idx_products_category_price_name ON products (category, price, name);
-- 或者,如果 name 需要前綴索引
-- CREATE INDEX idx_products_category_price_name ON products (category, price, name(20));

6. 驗(yàn)證索引效果

添加索引后,必須驗(yàn)證它是否被正確使用且有效:

  • 使用 EXPLAIN:
    • 獲取 Spring Boot 應(yīng)用生成的 SQL。
    • 用實(shí)際參數(shù)替換占位符。
    • 在 MySQL 客戶端執(zhí)行 EXPLAIN [your SQL query];。
    • 檢查輸出:
      • key 列是否顯示了你期望使用的索引名?
      • type 列是否是較優(yōu)的類型(如 refrangeeq_ref),避免 ALL?
      • rows 列估計(jì)掃描的行數(shù)是否顯著減少?
      • Extra 列是否有 Using filesort 或 Using temporary?是否出現(xiàn)了 Using index(覆蓋索引)?
  • 性能測試:
    • 在測試環(huán)境模擬負(fù)載,對比添加索引前后的查詢響應(yīng)時(shí)間。
  • 監(jiān)控:
    • 觀察 APM 工具中對應(yīng)數(shù)據(jù)庫調(diào)用的耗時(shí)變化。
    • 觀察慢查詢?nèi)罩局?,之前的?SQL 是否消失或頻率降低。

總結(jié):

在 Spring Boot 項(xiàng)目中優(yōu)化 SQL 查詢性能,使用索引是關(guān)鍵。核心步驟包括:識別慢查詢 -> 理解查詢模式 -> 選擇合適的索引類型(單列、聯(lián)合、覆蓋等) -> 使用數(shù)據(jù)庫遷移工具 (Flyway/Liquibase) 在版本化的 SQL 腳本中創(chuàng)建索引 -> 使用 EXPLAIN 和監(jiān)控驗(yàn)證效果。

以上就是SpringBoot使用索引來優(yōu)化SQL查詢的詳細(xì)步驟的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot索引優(yōu)化SQL查詢的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Java如何利用線程池和Redis實(shí)現(xiàn)高效數(shù)據(jù)入庫

    Java如何利用線程池和Redis實(shí)現(xiàn)高效數(shù)據(jù)入庫

    文章介紹了如何利用線程池和Redis在高并發(fā)環(huán)境中實(shí)現(xiàn)高效的數(shù)據(jù)入庫,通過將數(shù)據(jù)首先存儲在Redis緩存中,然后利用線程池定期批量入庫處理,確保系統(tǒng)的性能和穩(wěn)定性,主要組件包括BatchDataStorageService、CacheService和RedisUtils等
    2025-02-02
  • java 中設(shè)計(jì)模式(裝飾設(shè)計(jì)模式)的實(shí)例詳解

    java 中設(shè)計(jì)模式(裝飾設(shè)計(jì)模式)的實(shí)例詳解

    這篇文章主要介紹了java 中設(shè)計(jì)模式(裝飾設(shè)計(jì)模式)的實(shí)例詳解的相關(guān)資料,希望通過本文能幫助到大家,需要的朋友可以參考下
    2017-09-09
  • Windows下將JAVA?jar注冊成windows服務(wù)的方法

    Windows下將JAVA?jar注冊成windows服務(wù)的方法

    這篇文章主要介紹了Windows下將JAVA?jar注冊成windows服務(wù)的方法,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-07-07
  • 從JVM的內(nèi)存管理角度分析Java的GC垃圾回收機(jī)制

    從JVM的內(nèi)存管理角度分析Java的GC垃圾回收機(jī)制

    這篇文章主要介紹了從JVM的內(nèi)存管理角度分析Java的GC垃圾回收機(jī)制,帶有GC是Java語言的重要特性之一,需要的朋友可以參考下
    2015-11-11
  • Mybatis日志參數(shù)快速替換占位符工具的詳細(xì)步驟

    Mybatis日志參數(shù)快速替換占位符工具的詳細(xì)步驟

    這篇文章主要介紹了Mybatis日志參數(shù)快速替換占位符工具的詳細(xì)步驟,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-08-08
  • java Socket實(shí)現(xiàn)網(wǎng)頁版在線聊天

    java Socket實(shí)現(xiàn)網(wǎng)頁版在線聊天

    這篇文章主要為大家詳細(xì)介紹了java Socket實(shí)現(xiàn)網(wǎng)頁版在線聊天具體代碼,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-05-05
  • Java 實(shí)戰(zhàn)項(xiàng)目之疫情人員流動管理系統(tǒng)詳解

    Java 實(shí)戰(zhàn)項(xiàng)目之疫情人員流動管理系統(tǒng)詳解

    讀萬卷書不如行萬里路,只學(xué)書上的理論是遠(yuǎn)遠(yuǎn)不夠的,只有在實(shí)戰(zhàn)中才能獲得能力的提升,本篇文章手把手帶你用Java實(shí)現(xiàn)一個(gè)疫情人員流動管理系統(tǒng),大家可以在過程中查缺補(bǔ)漏,提升水平
    2021-11-11
  • SpringMVC獲取請求參數(shù)筆記整理

    SpringMVC獲取請求參數(shù)筆記整理

    本文記錄和分享在學(xué)習(xí)Spring MVC過程中的筆記,通過案例示例代碼分析給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-04-04
  • 使用spring?jpa?如何給外鍵賦值

    使用spring?jpa?如何給外鍵賦值

    這篇文章主要介紹了使用spring?jpa?如何給外鍵賦值,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-06-06
  • JAVA十大排序算法之堆排序詳解

    JAVA十大排序算法之堆排序詳解

    這篇文章主要介紹了java中的冒泡排序,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考
    2021-08-08

最新評論