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

SpringBoot3集成Calcite多數(shù)據(jù)源查詢的實戰(zhàn)示例小結

 更新時間:2026年02月09日 10:22:02   作者:暴躁代碼  
本文介紹了Spring Boot 3集成Apache Calcite實現(xiàn)多數(shù)據(jù)源查詢的實戰(zhàn)指南,本文通過實例代碼給大家講解的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友參考下吧

前言:跨庫查詢的痛,誰懂?

凌晨兩點被告警電話叫醒,訂單查詢接口超時,客服群炸開了鍋。排查了一圈才發(fā)現(xiàn)問題的根源:訂單數(shù)據(jù)在 MySQL,用戶信息在 PostgreSQL,行為畫像在 MongoDB,訪問日志存在 Hive。四套 DAO 層相互牽制,改動任何一個字段就像推倒多米諾骨牌一樣引發(fā)連鎖反應。

企業(yè)項目一旦數(shù)據(jù)源增多,"多數(shù)據(jù)源管理"很快就演變成維護黑洞。每新增一個數(shù)據(jù)源,就要新建一套 DAO 配置、數(shù)據(jù)源連接池、事務管理。復用率低不說,還把業(yè)務邏輯和數(shù)據(jù)訪問層死死綁在一起。最要命的是,不同數(shù)據(jù)源的字段命名規(guī)范不統(tǒng)一,user_levelcustomer_level、user_grade 混著用,改一個字段名,訂單系統(tǒng)、用戶系統(tǒng)、風控系統(tǒng)、報表系統(tǒng)全線報錯,誰改誰背鍋。

傳統(tǒng)方案要么做全量數(shù)據(jù)同步到數(shù)倉,要么寫一堆分布式事務代碼,要么在內(nèi)存里手動 JOIN。結果就是:延遲不可避免,查詢結果拿到的往往是舊數(shù)據(jù)快照;性能是硬傷,MySQL 擅長點查和小范圍索引掃描,MongoDB 天生文檔檢索,Hive 批量掃描效率高,Kafka 流式處理,一刀切的內(nèi)存聚合方式很快就把 JVM 打爆了,查詢延遲像篩子一樣抖個不停。

一、重新認識 Apache Calcite:不只是數(shù)據(jù)庫,更是查詢大腦

很多人第一次聽到 “Apache Calcite”,直覺反應是"又一個數(shù)據(jù)庫"。這個理解完全錯了。

Calcite 本質上是一個動態(tài)數(shù)據(jù)管理框架,專注于提供 SQL 解析、查詢優(yōu)化和跨數(shù)據(jù)源連接的基礎能力,但不涉及數(shù)據(jù)的存儲和處理。這種設計哲學讓它具備了極其靈活的適配能力。

它主要做四件事:

1. SQL 解析與驗證

將用戶提交的 SQL 語句解析為抽象語法樹(AST),并進行語義分析,驗證表名、列名是否存在,數(shù)據(jù)類型是否匹配等。就像把一句自然語言翻譯成結構化的指令樹。

2. 查詢優(yōu)化

這是 Calcite 的核心殺手锏。它提供基于規(guī)則優(yōu)化(RBO)和基于代價優(yōu)化(CBO)兩種策略:

  • 規(guī)則優(yōu)化:通過預設規(guī)則重寫查詢,比如謂詞下推、投影裁剪、JOIN 重排
  • 代價優(yōu)化:根據(jù)統(tǒng)計信息估算不同執(zhí)行計劃的成本,選擇最優(yōu)方案

3. 數(shù)據(jù)源適配

Calcite 通過適配器(Adapter)機制連接各種數(shù)據(jù)源,包括:

  • 關系型數(shù)據(jù)庫:MySQL、PostgreSQL、Oracle、SQL Server
  • NoSQL 數(shù)據(jù)庫:MongoDB、Cassandra、Redis
  • 文件系統(tǒng):CSV、JSON、Parquet、Excel
  • 大數(shù)據(jù)引擎:Hive、Spark、Kafka

甚至還可以自定義適配器,讓任何數(shù)據(jù)源都能接入。

4. 跨數(shù)據(jù)源查詢

能夠連接不同類型的數(shù)據(jù)源,通過適配器統(tǒng)一抽象不同數(shù)據(jù)源的操作,將查詢分解為各數(shù)據(jù)源可處理的子查詢,然后合并結果。

一句話總結:Calcite 把"數(shù)據(jù)在哪"和"怎么查"徹底拆開了。你寫一句標準 SQL,它負責解析、優(yōu)化、拆分,最終把查詢路由到各個數(shù)據(jù)源執(zhí)行。

很多熟悉的系統(tǒng)都在用 Calcite:Flink SQL 用它做解析與優(yōu)化,Hive 的 CBO 用它打底,Drill、Kylin、Druid 都接入了它的能力。

二、Spring Boot 3 集成 Calcite 實戰(zhàn)指南

2.1 核心依賴引入

第一步是添加 Maven 依賴。在 pom.xml 中引入 Calcite 核心包、對應數(shù)據(jù)源的適配器,以及 MyBatis Plus 的核心依賴。

<!-- Calcite 核心依賴 -->
<dependency>
    <groupId>org.apache.calcite</groupId>
    <artifactId>calcite-core</artifactId>
    <version>1.36.0</version>
</dependency>
<!-- MySQL 適配器 -->
<dependency>
    <groupId>org.apache.calcite</groupId>
    <artifactId>calcite-mysql</artifactId>
    <version>1.36.0</version>
</dependency>
<!-- MongoDB 適配器 -->
<dependency>
    <groupId>org.apache.calcite</groupId>
    <artifactId>calcite-mongodb</artifactId>
    <version>1.36.0</version>
</dependency>
<!-- MyBatis Plus 核心依賴(需要適配 Spring Boot 3) -->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.5.5</version>
</dependency>
<!-- 數(shù)據(jù)源連接池 -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid-spring-boot-starter</artifactId>
    <version>1.2.20</version>
</dependency>

三個避坑點必須強調:

  1. Calcite 所有組件版本必須統(tǒng)一。核心包和適配器版本要一致,否則容易出現(xiàn)類加載異常。
  2. MyBatis Plus 要選適配 Spring Boot 3 的版本。必須是 3.5.3 及以上版本,舊版本不支持。
  3. 一定要加連接池依賴。MyBatis Plus 需要連接池支持才能正常管理 Calcite 數(shù)據(jù)源。

2.2 編寫 Calcite 模型文件

模型文件是 Calcite 識別數(shù)據(jù)源的關鍵,通常使用 JSON 格式,放在 resources 目錄下,命名為 calcite-model.json。

下面是一個適配 MySQL 和 MongoDB 雙數(shù)據(jù)源的示例:

{
  "version": "1.0",
  "defaultSchema": "ecommerce",
  "schemas": [
    {
      "name": "ecommerce",
      "type": "custom",
      "factory": "org.apache.calcite.adapter.jdbc.JdbcSchema$Factory",
      "operand": {
        "jdbcUrl": "jdbc:mysql://localhost:3306/ecommerce_order?useSSL=false&serverTimezone=UTC",
        "username": "root",
        "password": "123456",
        "driver": "com.mysql.cj.jdbc.Driver"
      }
    },
    {
      "name": "user_mongo",
      "type": "custom",
      "factory": "org.apache.calcite.adapter.mongodb.MongoSchema$Factory",
      "operand": {
        "host": "localhost",
        "port": 27017,
        "database": "user_db",
        "collection": "user_info"
      }
    }
  ]
}

關鍵配置說明:

  • defaultSchema:默認查詢的 schema,可省略。如果省略,查詢時需要指定 schema 名稱(如 ecommerce.order、user_mongo.user_info)。
  • factory:對應數(shù)據(jù)源的適配器工廠類。Calcite 已為主流數(shù)據(jù)源提供現(xiàn)成工廠,自定義數(shù)據(jù)源需要實現(xiàn)自己的工廠類。
  • operand:數(shù)據(jù)源連接參數(shù),根據(jù)數(shù)據(jù)源類型不同配置不同參數(shù)(如 MySQL 的 jdbcUrl、MongoDB 的 host/port)。

2.3 Spring Boot 集成 Calcite + MyBatis Plus 核心配置

這一步是集成的核心,主要分兩步走:

  1. 配置好 Calcite 數(shù)據(jù)源
  2. 讓 MyBatis Plus 使用這個數(shù)據(jù)源,并配置 Mapper 掃描、分頁插件等基礎參數(shù)
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.apache.calcite.jdbc.CalciteConnection;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.DriverManager;
import java.util.Properties;
@Configuration
@MapperScan(basePackages = "com.example.calcite.mapper")
public class CalciteMybatisPlusConfig {
    // 1. 配置 Calcite 數(shù)據(jù)源
    @Bean
    public DataSource calciteDataSource() throws Exception {
        Properties props = new Properties();
        props.setProperty("model", "classpath:calcite-model.json");
        Connection connection = DriverManager.getConnection("jdbc:calcite:", props);
        CalciteConnection calciteConnection = connection.unwrap(CalciteConnection.class);
        return calciteConnection.getDataSource();
    }
    // 2. 配置 MyBatis Plus 的 SqlSessionFactory,指定使用 Calcite 數(shù)據(jù)源
    @Bean
    public SqlSessionFactory sqlSessionFactory(DataSource calciteDataSource) throws Exception {
        MybatisSqlSessionFactoryBean sessionFactory = new MybatisSqlSessionFactoryBean();
        // 注入 Calcite 數(shù)據(jù)源
        sessionFactory.setDataSource(calciteDataSource);
        // 配置 Mapper.xml 文件路徑
        sessionFactory.setMapperLocations(
            new PathMatchingResourcePatternResolver().getResources("classpath:mapper/*.xml")
        );
        // 配置 MyBatis Plus 全局參數(shù)
        org.apache.ibatis.session.Configuration configuration = 
            new org.apache.ibatis.session.Configuration();
        configuration.setMapUnderscoreToCamelCase(true); // 下劃線轉駝峰
        sessionFactory.setConfiguration(configuration);
        // 注入 MyBatis Plus 插件
        sessionFactory.setPlugins(mybatisPlusInterceptor());
        return sessionFactory.getObject();
    }
    // 3. MyBatis Plus 分頁插件
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(
            new PaginationInnerInterceptor(DbType.MYSQL) // 適配 Calcite 兼容的 MySQL 語法
        );
        return interceptor;
    }
    // 4. 配置事務管理器
    @Bean
    public PlatformTransactionManager transactionManager(DataSource calciteDataSource) {
        return new DataSourceTransactionManager(calciteDataSource);
    }
}

核心邏輯梳理:

先通過 Calcite 創(chuàng)建統(tǒng)一的數(shù)據(jù)源,再把它注入到 MyBatis Plus 的 SqlSessionFactory 里。這樣一來,后續(xù)寫代碼完全是 MyBatis Plus 的熟悉風格,無論是 Mapper 接口還是 XML 映射文件,都能直接用,跨數(shù)據(jù)源查詢的復雜邏輯全交給 Calcite 處理。

2.4 核心查詢實現(xiàn)

定義實體類

使用 Lombok 注解定義 VO 類,包含訂單和用戶信息:

import lombok.Data;
@Data
public class UserOrderVO {
    // 訂單信息
    private String orderId;
    private String orderTime;
    private Double amount;
    // 用戶信息
    private String userName;
    private String phone;
    private String userId;
}

定義 Mapper 接口

繼承 BaseMapper 獲得 MyBatis Plus 基礎 CRUD 能力,使用 @Select 注解編寫跨數(shù)據(jù)源關聯(lián) SQL:

import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import java.util.List;
@Mapper
public interface UserOrderMapper extends BaseMapper<UserOrderVO> {
    // 注解方式編寫跨數(shù)據(jù)源關聯(lián) SQL
    @Select("SELECT " +
            "  o.order_id AS orderId, " +
            "  o.order_time AS orderTime, " +
            "  o.amount, " +
            "  u.user_name AS userName, " +
            "  u.phone " +
            "FROM ecommerce.orders o " +
            "JOIN user_mongo.user_info u ON o.user_id = u.user_id " +
            "WHERE o.user_id = #{userId}")
    List<UserOrderVO> queryUserOrderByUserId(String userId);
}

如果使用 XML 方式:

resources/mapper/UserOrderMapper.xml 中編寫:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" 
    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.calcite.mapper.UserOrderMapper">
    <select id="queryUserOrderByUserIdWithXml" resultType="com.example.calcite.entity.UserOrderVO">
        SELECT
            o.order_id AS orderId,
            o.order_time AS orderTime,
            o.amount,
            u.user_name AS userName,
            u.phone
        FROM ecommerce.orders o
        JOIN user_mongo.user_info u ON o.user_id = u.user_id
        WHERE o.user_id = #{userId}
    </select>
</mapper>

編寫 Service 層

繼承 ServiceImpl 實現(xiàn)業(yè)務邏輯:

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class UserOrderService extends ServiceImpl<UserOrderMapper, UserOrderVO> {
    public List<UserOrderVO> getUserOrderByUserId(String userId) {
        // 直接調用 Mapper 接口方法
        return this.baseMapper.queryUserOrderByUserId(userId);
    }
    // 如果使用 XML 方式:
    public List<UserOrderVO> getUserOrderByUserIdWithXml(String userId) {
        return this.baseMapper.queryUserOrderByUserIdWithXml(userId);
    }
}

編寫 Controller 層

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
public class CrossDataSourceQueryController {
    @Autowired
    private UserOrderService userOrderService;
    @GetMapping("/user/order/{userId}")
    public List<UserOrderVO> queryUserOrder(@PathVariable String userId) {
        // 調用 Service 方法,返回跨數(shù)據(jù)源查詢結果
        return userOrderService.getUserOrderByUserId(userId);
    }
}

三個關鍵點:

  1. 實體類字段要和查詢結果列名對應。使用別名適配下劃線轉駝峰更省心(如 o.order_id AS orderId)。
  2. Mapper 接口繼承 BaseMapper 后,MyBatis Plus 的分頁、條件構造器這些功能都能正常使用。
  3. SQL 查詢要帶 schema 前綴。比如 ecommerce.orders、user_mongo.user_info,明確指定數(shù)據(jù)源。

三、經(jīng)典使用場景深度解析

3.1 多系統(tǒng)數(shù)據(jù)融合查詢

場景痛點:

大型企業(yè)里數(shù)據(jù)分散在不同系統(tǒng),訂單系統(tǒng)用 MySQL,用戶系統(tǒng)用 MongoDB 存行為數(shù)據(jù),庫存系統(tǒng)用 PostgreSQL。傳統(tǒng)做法需要分別調用三個系統(tǒng)接口,在內(nèi)存中手動整合數(shù)據(jù),效率低且容易出錯。一旦某個系統(tǒng)字段變更,所有調用方都要改。

Calcite 解決方案:

用 Calcite 分別適配三個數(shù)據(jù)源后,只要寫一套標準 SQL 就能實現(xiàn)跨數(shù)據(jù)源關聯(lián)查詢。業(yè)務層完全不用管數(shù)據(jù)存在哪,專注核心業(yè)務邏輯。

價值收益:

  • 開發(fā)效率提升 50% 以上。不用寫重復的接口調用和數(shù)據(jù)整合代碼。
  • Calcite 的查詢優(yōu)化器會自動優(yōu)化關聯(lián)邏輯。先把時間過濾推給 MySQL 做索引掃描,再把用戶 ID 集合下推給 MongoDB 做 IN 查詢,最后在本地完成 JOIN 和聚合。
  • 查詢效率也能跟上。謂詞下推、投影裁剪、JOIN 重排這些優(yōu)化都是自動的,不用手動摳。

3.2 實時數(shù)據(jù)與離線數(shù)據(jù)聯(lián)動查詢

場景需求:

運營需要實時查看今日訂單加近 30 天歷史訂單的匯總數(shù)據(jù)。實時訂單數(shù)據(jù)存在 Kafka 里,歷史訂單數(shù)據(jù)存在 Hive 里。

傳統(tǒng)方案:

需要開發(fā)兩套查詢邏輯,分別從 Kafka 和 Hive 拉數(shù)據(jù),再在內(nèi)存中合并。開發(fā)成本高,而且數(shù)據(jù)同步有延遲,合并后的結果未必是實時的。

Calcite 解決方案:

用 Calcite 的 Kafka 適配器和 Hive 適配器,把實時流數(shù)據(jù)和離線數(shù)據(jù)放到同一個查詢體系里。寫一條 SQL 就能實現(xiàn)實時加離線數(shù)據(jù)的聯(lián)合查詢:

SELECT 
  product_id,
  SUM(amount) AS total_amount
FROM (
  -- 實時數(shù)據(jù)(Kafka)
  SELECT product_id, amount FROM realtime.orders WHERE dt = CURRENT_DATE
  UNION ALL
  -- 離線數(shù)據(jù)(Hive)
  SELECT product_id, amount FROM hive.orders WHERE dt >= CURRENT_DATE - INTERVAL '30' DAY
) combined
GROUP BY product_id

價值收益:

  • 省去了數(shù)據(jù)同步成本。不用把 Kafka 數(shù)據(jù)實時同步到 Hive,也不用把 Hive 數(shù)據(jù)預聚合出來。
  • 兼顧實時性和準確性。Kafka 的實時數(shù)據(jù) + Hive 的歷史數(shù)據(jù),聯(lián)合查詢結果既有實時性又有完整性。

3.3 自定義數(shù)據(jù)源適配

場景需求:

企業(yè)里有很多 CSV、Excel、Parquet 格式的文件數(shù)據(jù),需要集成到業(yè)務系統(tǒng)中查詢。

傳統(tǒng)方案:

先把這些文件導入數(shù)據(jù)庫(如 MySQL),然后再提供查詢接口。數(shù)據(jù)遷移成本高,而且數(shù)據(jù)更新后需要重新導入。

Calcite 解決方案:

Calcite 內(nèi)置了文件適配器,支持直接查詢這些文件數(shù)據(jù),根本不用導入數(shù)據(jù)庫。結合 Spring Boot 3 的文件上傳功能,還能實現(xiàn)文件上傳后直接用 SQL 查詢的需求。

模型配置示例:

{
  "name": "files",
  "type": "custom",
  "factory": "org.apache.calcite.adapter.csv.CsvSchemaFactory",
  "operand": {
    "directory": "/data/files",
    "flavor": "mysql"
  }
}

查詢示例:

-- 直接查詢 CSV 文件
SELECT * FROM files.sales_data WHERE region = 'East'
-- 與其他數(shù)據(jù)源關聯(lián)
SELECT 
  f.product_id,
  p.product_name,
  f.sales_amount
FROM files.sales_data f
JOIN ecommerce.products p ON f.product_id = p.id

四、避坑指南:集成注意事項

4.1 版本一致性

問題:

Calcite 核心依賴和各數(shù)據(jù)源適配器的版本必須一致,不然很容易出現(xiàn)類加載異常。

避坑技巧:

  • 推薦使用 Calcite 1.36.0 版本。這個版本穩(wěn)定性好,適配器齊全。
  • 不要混用不同版本。比如 calcite-core 1.36.0 + calcite-mysql 1.35.0,這種組合極易出問題。
  • mvn dependency:tree 檢查依賴沖突。

4.2 模型文件配置規(guī)范

問題:

Schema 名稱、表名要清晰,別重復。數(shù)據(jù)源的地址、端口、賬號密碼這些連接參數(shù)一定要準確。

避坑技巧:

  • 按業(yè)務域劃分 Schema。比如 retail.orders、crm.users,一眼能看懂歸屬。
  • 表名使用有意義的名稱。避免用 table1、table2 這種模糊命名。
  • 連接參數(shù)做好環(huán)境隔離。開發(fā)、測試、生產(chǎn)環(huán)境用不同的配置文件。

4.3 數(shù)據(jù)源性能考慮

問題:

跨數(shù)據(jù)源查詢的性能取決于最慢的那個數(shù)據(jù)源。如果 MySQL 查詢很快,但 MongoDB 慢,整體查詢還是會被拖慢。

避坑技巧:

  • 確保每個數(shù)據(jù)源自身性能沒問題。定期檢查慢查詢,優(yōu)化索引。
  • 合理使用謂詞下推。Calcite 會自動把過濾條件推到數(shù)據(jù)源執(zhí)行,但要檢查執(zhí)行計劃,確保推下去了。
  • 對小表考慮廣播到內(nèi)存,避免大表大表硬碰硬。

4.4 SQL 方言差異

問題:

不同數(shù)據(jù)源支持的 SQL 語法有差異。比如 grouping sets、窗口函數(shù)、子查詢某些源不完全支持。

避坑技巧:

  • 查詢前先測試。開發(fā)階段用 Calcite 的 EXPLAIN 功能看執(zhí)行計劃。
  • 不支持的語法要降級實現(xiàn)。比如某個源不支持窗口函數(shù),就改用子查詢。
  • 定期查看 Calcite 和各數(shù)據(jù)源的官方文檔,了解語法支持情況。

五、優(yōu)化小技巧:讓查詢更快更穩(wěn)

5.1 啟用 Calcite 緩存

元數(shù)據(jù)緩存:

避免每次查詢都重新加載 Schema 結構,減少重復解析和元數(shù)據(jù)查詢的時間。

props.setProperty("calcite.metadataCacheSize", "1000");

查詢計劃緩存:

對相同 SQL 查詢,緩存執(zhí)行計劃,提升重復查詢效率。

props.setProperty("calcite.parser.factory", 
    "org.apache.calcite.sql.parser.impl.SqlParserImpl#FACTORY");

5.2 優(yōu)化 SQL 寫法

能下推就下推:

盡量避免復雜的多表關聯(lián)在 Calcite 層執(zhí)行,把過濾條件下推到數(shù)據(jù)源。

示例:

-- 不好的寫法:先全量掃描再過濾
SELECT * FROM ecommerce.orders o JOIN user_mongo.users u 
  ON o.user_id = u.user_id 
  WHERE o.create_time >= '2025-01-01'
-- 好的寫法:時間過濾下推到 MySQL
SELECT * FROM (
  SELECT * FROM ecommerce.orders WHERE create_time >= '2025-01-01'
) o 
JOIN user_mongo.users u ON o.user_id = u.user_id

選擇必要字段:

避免 SELECT *,只查詢需要的字段,減少數(shù)據(jù)傳輸量。

5.3 自定義優(yōu)化規(guī)則

如果是特別復雜的業(yè)務場景,可以自己實現(xiàn) RelOptRule 接口,寫自定義的查詢優(yōu)化規(guī)則。

示例場景:

強制某些過濾條件先執(zhí)行,或者把某個維表標成可廣播。

代碼示例:

import org.apache.calcite.rel.RelNode;
import org.apache.calcite.rel.rules.RelOptRule;
public class CustomRule extends RelOptRule {
    public CustomRule() {
        super(operand(FilterRel.class, any()));
    }
    @Override
    public boolean matches(RelOptRuleCall call) {
        // 自定義匹配邏輯
        return true;
    }
    @Override
    public void onMatch(RelOptRuleCall call) {
        // 自定義優(yōu)化邏輯
        FilterRel filter = call.rel(0);
        // ... 重寫查詢計劃
    }
}

5.4 開啟 EXPLAIN 分析

定期分析慢查詢的執(zhí)行計劃,找出性能瓶頸:

EXPLAIN PLAN FOR 
SELECT * FROM ecommerce.orders o 
JOIN user_mongo.user_info u ON o.user_id = u.user_id 
WHERE o.user_id = '123456'

重點關注:

  • 拉回來的行數(shù)
  • 下推的過濾條件
  • JOIN 順序
  • 是否使用了索引

六、邊界與選型:什么時候不該用 Calcite

6.1 不適合的場景

強事務 OLTP 場景:

Calcite 不適合替代 OLTP 數(shù)據(jù)庫的核心業(yè)務場景。對于強事務需求,如轉賬扣減、庫存凍結,仍需使用傳統(tǒng)數(shù)據(jù)庫,跨庫分布式事務別硬湊。

大規(guī)模分布式計算:

如果要的是超大規(guī)模分布式計算,直接開 Trino、Presto 集群。Calcite 更像"查詢大腦",把解析和優(yōu)化做好,執(zhí)行靠接出來的源,或者你自己寫執(zhí)行器。

高頻點查場景:

對于高頻單表點查,直接用數(shù)據(jù)源自身的驅動可能更高效,沒必要經(jīng)過 Calcite 這一層。

6.2 適合的場景

  • 數(shù)據(jù)中臺:作為統(tǒng)一查詢層
  • 多系統(tǒng)整合:跨部門、跨系統(tǒng)的數(shù)據(jù)融合
  • 實時分析:流批一體化分析
  • 數(shù)據(jù)虛擬化:免 ETL,直接查詢原始數(shù)據(jù)源

6.3 與其他方案的對比

方案優(yōu)點缺點適用場景
Calcite嵌入式、自定義規(guī)則強、輕量級分布式能力弱Spring Boot 應用內(nèi)集成、規(guī)則定制化需求強
Trino/Presto分布式、大規(guī)模計算學習曲線陡、集群運維成本高數(shù)據(jù)倉庫、大規(guī)模分析
ETL穩(wěn)定、數(shù)據(jù)一致性好實時性差、開發(fā)量大離線數(shù)倉、數(shù)據(jù)同步為主
BI 平臺易用、可視化強依賴工具、定制化受限業(yè)務分析、報表展示

七、團隊協(xié)作與治理

7.1 統(tǒng)一 SQL 編碼規(guī)范

  • 強制使用 Schema.table 格式訪問表,避免歧義。
  • 禁用 SELECT *,只查詢必要字段。
  • 統(tǒng)一字段命名規(guī)范,下劃線和駝峰明確約定。

7.2 建立查詢評審機制

  • 復雜查詢需經(jīng)過架構評審。
  • 評審重點關注:查詢邏輯、執(zhí)行計劃、數(shù)據(jù)量預估。
  • 評審通過才能上線。

7.3 監(jiān)控與告警

  • 查詢性能監(jiān)控:對慢查詢(超過 1 秒)進行告警。
  • 跨源查詢數(shù)據(jù)量監(jiān)控:記錄每次查詢涉及的行數(shù),及時發(fā)現(xiàn)異常。
  • 連接池監(jiān)控:監(jiān)控各數(shù)據(jù)源連接池使用情況,避免連接耗盡。

7.4 定期清理與維護

  • 跨域配置按季度清理:沒用的數(shù)據(jù)源配置就摘掉,避免"歷史債務"不斷疊加。
  • 元數(shù)據(jù)定期更新:數(shù)據(jù)源表結構變更后,及時更新模型文件。
  • 規(guī)則庫維護:自定義優(yōu)化規(guī)則要定期review,避免規(guī)則過時。

八、總結

Spring Boot 3 集成 Apache Calcite,最大的變化是:

  • 業(yè)務寫 SQL,不用管數(shù)據(jù)在哪
  • 適配器管"去哪兒查",自動路由到對應數(shù)據(jù)源
  • 優(yōu)化器管"怎么查得更省",自動下推、自動優(yōu)化
  • 工程師把精力放回業(yè)務規(guī)則,而不是堆 DAO、摳連接

它不是萬能鑰匙,但在多源并存的公司里,它確實把"跨庫地獄"挪走了一大半。

用對地方,別把它硬拽去當分布式 OLTP,剩下的,交給監(jiān)控、規(guī)范、演練和一點點耐心。

技術選型的本質,不是找最先進的工具,而是找最合適的工具。

參考資料:

  • Apache Calcite 官方文檔:https://calcite.apache.org/
  • Spring Boot 3 官方文檔
  • MyBatis Plus 官方文檔
  • Apache Flink、Hive 等大數(shù)據(jù)系統(tǒng)的 Calcite 集成案例

到此這篇關于SpringBoot3集成Calcite多數(shù)據(jù)源查詢實戰(zhàn)筆記-7407466045的文章就介紹到這了,更多相關SpringBoot3 Calcite多數(shù)據(jù)源查詢內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Redisson分布式信號量RSemaphore的使用超詳細講解

    Redisson分布式信號量RSemaphore的使用超詳細講解

    這篇文章主要介紹了Redisson分布式信號量RSemaphore的使用,基于Redis的Redisson的分布式信號量RSemaphore采用了與java.util.concurrent.Semaphore相似的接口和用法
    2023-02-02
  • Java注釋代碼執(zhí)行方法解析

    Java注釋代碼執(zhí)行方法解析

    這篇文章主要介紹了Java注釋代碼執(zhí)行方法解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-05-05
  • Java實現(xiàn)壓縮圖片大小

    Java實現(xiàn)壓縮圖片大小

    這篇文章主要為大家詳細介紹了Java實現(xiàn)壓縮圖片大小,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-04-04
  • Java多線程死鎖與資源限制操作

    Java多線程死鎖與資源限制操作

    這篇文章主要介紹了Java多線程死鎖與資源限制操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-09-09
  • SpringCache 緩存使用方案總結

    SpringCache 緩存使用方案總結

    在基于SpringBoot3.x集成JetCache時遇到問題,決定采用SpringCache作為替代方案,本文詳細介紹了SpringCache本地緩存(Caffeine)和本地+遠程(Redis)混合緩存的配置和使用方法,并總結了常用的緩存注解參數(shù)及其含義,感興趣的朋友跟隨小編一起看看吧
    2026-02-02
  • Java操作ElasticSearch的實例詳解

    Java操作ElasticSearch的實例詳解

    Elasticsearch?是一個分布式的搜索和分析引擎,廣泛用于全文搜索、日志分析等場景,本文將介紹如何在?Java?應用中使用?Elasticsearch?客戶端來連接和操作?Elasticsearch?集群,希望對大家有所幫助
    2025-01-01
  • Java實現(xiàn)讀取Jar文件屬性的方法詳解

    Java實現(xiàn)讀取Jar文件屬性的方法詳解

    這篇文章主要為大家詳細介紹了如何利用Java語言實現(xiàn)讀取Jar文件屬性的功能,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學習一下
    2022-08-08
  • 使用JAVA判斷凸多邊形的示例代碼

    使用JAVA判斷凸多邊形的示例代碼

    本文提供了使用JAVA判斷凸多邊形的示例代碼供大家參考學習,需要的朋友可以看一下
    2013-11-11
  • Spring大白話之三級緩存如何解決循環(huán)依賴問題

    Spring大白話之三級緩存如何解決循環(huán)依賴問題

    Spring通過三級緩存(singletonObjects、earlySingletonObjects、singletonFactories)解決單例循環(huán)依賴,三級緩存使用Lambda表達式提前暴露bean的早期引用,確保在遞歸調用時能夠正確獲取對象實例,避免死循環(huán)
    2025-02-02
  • Java泛型<T> T與T的使用方法詳解

    Java泛型<T> T與T的使用方法詳解

    這篇文章主要介紹了Java泛型<T> T與T的使用方法詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-07-07

最新評論

大同县| 通化市| 本溪市| 鲁甸县| 平昌县| 嘉黎县| 洛川县| 岚皋县| 阳朔县| 尼勒克县| 永登县| 景谷| 邹城市| 白银市| 石景山区| 浑源县| 湟源县| 襄垣县| 塔城市| 阿图什市| 丁青县| 福建省| 大化| 金门县| 辽中县| 双江| 岳阳县| 廉江市| 洛阳市| 鱼台县| 太白县| 盱眙县| 壤塘县| 东乌珠穆沁旗| 南投市| 周口市| 东山县| 青冈县| 石门县| 图们市| 莱西市|