为什么 IRIS SQL 会比 Spring JDBC 更快?

文章目录

  • [为什么 IRIS SQL 会比 Spring JDBC 更快?](#为什么 IRIS SQL 会比 Spring JDBC 更快?)
  • [1. **数据库执行层级不同:IRIS SQL 是原生执行,而 Spring JDBC 只是"调用者"**](#1. 数据库执行层级不同:IRIS SQL 是原生执行,而 Spring JDBC 只是“调用者”)
      • [Spring JDBC 的执行路径:](#Spring JDBC 的执行路径:)
      • [IRIS 的执行路径(核心差异):](#IRIS 的执行路径(核心差异):)
  • [2. **IRIS 的存储引擎(Globals)结构天生比传统关系型数据库快**](#2. IRIS 的存储引擎(Globals)结构天生比传统关系型数据库快)
  • [3. IRIS 查询流程(极简)](#3. IRIS 查询流程(极简))
  • [4. 基本概念:什么是 Global?](#4. 基本概念:什么是 Global?)
  • [5. Globals 结构比页结构(Page)快太多:稀疏、有序、按键直接定位](#5. Globals 结构比页结构(Page)快太多:稀疏、有序、按键直接定位)
  • [6 . 索引本质上是 Global(稀疏多维数组),天然有序,遍历速度极快](#6 . 索引本质上是 Global(稀疏多维数组),天然有序,遍历速度极快)
  • [7. IRIS 的执行路径极短:SQL 层非常薄,没有大量中间对象](#7. IRIS 的执行路径极短:SQL 层非常薄,没有大量中间对象)
  • [8. 示例一:单条查询路径对比(IRIS vs MySQL/PostgreSQL)](#8. 示例一:单条查询路径对比(IRIS vs MySQL/PostgreSQL))
      • [MySQL/Postgres 查询一条记录的路径(非常多层)](#MySQL/Postgres 查询一条记录的路径(非常多层))
      • [IRIS 查找一条记录(几乎无中间层)](#IRIS 查找一条记录(几乎无中间层))
      • [对比示例(读取某个用户 ID=123)](#对比示例(读取某个用户 ID=123))
        • [MySQL/PostgreSQL 内部做的事情:](#MySQL/PostgreSQL 内部做的事情:)
        • [IRIS 内部做的事情:](#IRIS 内部做的事情:)
  • 性能差距示例
      • [同样是查询 100 万条数据中的一条](#同样是查询 100 万条数据中的一条)
  • [9 什么是 IRIS 的箭头语法(→)?](#9 什么是 IRIS 的箭头语法(→)?)
    • [传统数据库 JOIN 在多表时的结构问题](#传统数据库 JOIN 在多表时的结构问题)
      • [1. 扫描或索引查找 table A](#1. 扫描或索引查找 table A)
      • [2. 扫描或索引查找 table B](#2. 扫描或索引查找 table B)
      • [3. 构建临时 JOIN buffer / Hash table / Merge buffer](#3. 构建临时 JOIN buffer / Hash table / Merge buffer)
      • [4. 比较 key](#4. 比较 key)
      • [5. 输出结果](#5. 输出结果)
  • [10. IRIS 的箭头语法为什么快?](#10. IRIS 的箭头语法为什么快?)
  • [🟦 直观对比:同样的 3 表查询](#🟦 直观对比:同样的 3 表查询)
  • [🟢 IRIS 箭头语法:](#🟢 IRIS 箭头语法:)
  • [🔥 性能差距巨大](#🔥 性能差距巨大)
    • [**1. 箭头语法基于"对象引用",不是基于 JOIN**](#1. 箭头语法基于“对象引用”,不是基于 JOIN)
    • [**2. 箭头语法直接利用 IRIS 的 Global 多层树结构**](#2. 箭头语法直接利用 IRIS 的 Global 多层树结构)
    • [**3. 多表访问的成本是"节点跳转",而不是"多表 join"**](#3. 多表访问的成本是“节点跳转”,而不是“多表 join”)
    • [**4. 箭头语法可以无限深度引用**](#4. 箭头语法可以无限深度引用)
    • [**5. 执行计划简单、可预测、稳定**](#5. 执行计划简单、可预测、稳定)
  • [🧪 示例:深度 4 层引用](#🧪 示例:深度 4 层引用)
    • [🎯 为什么 IRIS 箭头语法查询多表比传统 SQL 更快?](#🎯 为什么 IRIS 箭头语法查询多表比传统 SQL 更快?)
  • [11. 传统数据库:复杂关系 = 多表 Join = 性能瓶颈 & 开发复杂](#11. 传统数据库:复杂关系 = 多表 Join = 性能瓶颈 & 开发复杂)
  • [IRIS:使用 Global(天然多维索引结构)可以直接定位值](#IRIS:使用 Global(天然多维索引结构)可以直接定位值)
      • [🔥 IRIS 中读取复杂关系只需要:](#🔥 IRIS 中读取复杂关系只需要:)
  • [3. 性能差异举例(真实结构对比)](#3. 性能差异举例(真实结构对比))
      • [假设要获取订单 → 用户 → 地址完整信息](#假设要获取订单 → 用户 → 地址完整信息)
    • [🔷 MySQL/PostgreSQL 的执行路径](#🔷 MySQL/PostgreSQL 的执行路径)
    • [🔷 IRIS Globals 的执行路径](#🔷 IRIS Globals 的执行路径)
  • [4. 举例说明速度差异](#4. 举例说明速度差异)
      • [MySQL 的 join 查询:](#MySQL 的 join 查询:)
      • [IRIS Global 查找:](#IRIS Global 查找:)
  • [5. 为什么 IRIS 可以直接取值?](#5. 为什么 IRIS 可以直接取值?)
  • [6. IRIS 多表复杂关系开发的优势总结](#6. IRIS 多表复杂关系开发的优势总结)
  • [7. 最形象的比喻(特别精准)](#7. 最形象的比喻(特别精准))
  • 总结(最核心一句话)

为什么 IRIS SQL 会比 Spring JDBC 更快?

IRIS 是"内存+持久化融合"的多模型数据库,执行 SQL 时不需要走 Java ORM 那些复杂的转换层,它是原生运行在数据库内核的高性能引擎。

1. 数据库执行层级不同:IRIS SQL 是原生执行,而 Spring JDBC 只是"调用者"

Spring JDBC 的执行路径:

Java → JDBC driver → 网络传输 → DB → SQL 解析 → 执行 → 返回结果 → JDBC → Java对象映射

每一步都要:

  • 进行数据序列化/反序列化
  • 做对象创建
  • 做数据类型转换
  • 消耗 GC
  • 走网络 TCP 调用

总传输和转换成本很高

IRIS 的执行路径(核心差异):

IRIS SQL 执行在 数据库内核 ,且底层语言是 高性能的原生运行时(ObjectScript 运行在数据库层面)

  • 不需要 Java 层处理
  • 不需要 ORM/JDBC 的多层映射
  • 不需要大量对象转换
  • SQL 优化器与存储引擎强绑定(类似 Oracle 内核)
  • 执行路径短得多

这是数据库层的"本地执行" VS Java API 的"远程调用"

自然会快很多。

2. IRIS 的存储引擎(Globals)结构天生比传统关系型数据库快

IRIS 不像 MySQL、PostgreSQL 那样使用:

  • page
  • tuple
  • B-tree page 分裂
  • buffer pool
  • redo log + binlog
  • MVCC / snapshot

IRIS 使用它独有的 Globals(基于平衡树的稀疏多维数组)

特性:

部署 IRIS Globals 传统 RDBMS B-tree
插入 O(log N),无 page 结构 page 分裂、页锁、buffer flush
查询 单节点定位,速度极快 要经过 buffer pool, page lookup
存储 无固定页结构,高压缩率 页固定16KB / 8KB
并发 无 MVCC 压力 MVCC、写放大、WAL

📌 IRIS 数据查找和更新本质是对多维树的直接定位,几乎没有中间层。

传统数据库每一步都会经历:

buffer pool → page → tuple → redo log → WAL

而 IRIS 没有这些复杂结构,所以 SQL 执行天然就快 🚀。

3. IRIS 查询流程(极简)

一个 SQL 查询最终会变成对 Globals 的访问:

sql 复制代码
直接定位键 → 读取节点

例如:

sql 复制代码
SELECT Name FROM Person WHERE ID = 1001

直接对应:

sql 复制代码
^PersonD(1001,"Name")

访问路径非常短:

sql 复制代码
Global Tree → 找到这个键 → 返回

没有 "页 → tuple → 行格式 → 版本解析 → buffer pool" 的步骤。

4. 基本概念:什么是 Global?

  • 逻辑模型:Global 看起来就是一个多维数组(多级下标)。例如:

    sql 复制代码
    SET ^Person(100,"name") = "张三"
    SET ^Person(100,"age") = 30

    这里 ^Person 是 global 名称,100,"name" 是 subscripts(下标)。

  • 稀疏:你可以只写你需要的下标,整个空间是稀疏的,不需要连续分配内存。

  • 持久化:写入的 global 被写到磁盘(global database 文件)并由 IRIS 管理其持久化、回滚与恢复。

  • 键值定位:每个存取都是"基于键"的操作(直接定位),不像关系数据库需要扫描页/行后再解析字段。

底层存储与组织(高层抽象)

注意:下面是对实现的高层、可理解的抽象说明(避免过度承诺具体内部实现细节),目的是帮助理解行为与性能。

  • 树/键结构 :Globals 在磁盘上以一种可按下标顺序索引的树/键结构存储(引擎提供对下标的快速查找和按序迭代能力)。
  • Extent(区段)管理:物理磁盘空间按 extent 分配,数据写入在这些 extent 中连续存放以提高 I/O 效率。
  • 稀疏键空间 :下标本质上被拼成排序键(按字典序/字节序),这样引擎能在键空间上做快速定位与范围扫描(比如 $ORDER / $QUERY)。
  • 内存缓存:常用的 global 节点被缓存在内存(缓存管理),减少磁盘 I/O。
  • Journal / 日志:为保证持久性,写操作会记录到 journal(写前日志或类似机制)以支持崩溃恢复与回滚。

访问模式与操作语义(为何高效)

  • O(log N) 或接近 O(1) 的键定位 :访问某个具体键(例如 ^G(a,b,c))不需要扫描整表,可以直接定位到对应节点或其附近位置。
  • 按键顺序高效遍历 :函数 $ORDER(^G(key))$QUERY 等允许从某个位置顺序遍历下一/上一个键,效率很高,适合范围查询与顺序扫描。
  • 原子性和事务性:对 Global 的写操作在事务内受 ACID 支持,可以回滚、提交且与 journaling 结合保证恢复。
  • 细粒度锁/乐观并发:引擎采用可以支持高并发的锁机制(局部锁或 MVCC 风格的并发控制),避免全局阻塞。

常用 Global 操作(ObjectScript 示例)

sql 复制代码
; 写入
SET ^Orders(1001,"status") = "NEW"
SET ^Orders(1001,"amount") = 299.5

; 读取
WRITE ^Orders(1001,"status")

; 遍历订单 id
SET id = ""
FOR  SET id = $ORDER(^Orders(id)) QUIT:id=""  DO
. WRITE "Order:", id, " status=", ^Orders(id,"status"), !
  • $ORDER:按字典序得到下一个(或上一个)下标。
  • $QUERY:在一些实现中提供比 $ORDER 更高效的顺序遍历(依据版本差异)。

与 SQL/类映射关系

  • SQL 表/列并不是另存的 :当你用 SQL CREATE TABLE 或 %Persistent 类时,IRIS 实际上在底层把表/索引映射到 Global 的某些节点布局上。也就是说 SQL 行/列/索引是 Global 的一个结构化视图或映射。
  • 索引:SQL 索引对应的也会是在另一个 global 中建立的键(反向映射),因此索引扫描同样是基于 global 键定位的高效操作。
  • 无缝跨模型访问:ObjectScript、SQL、Native routines 都能直接操作同样的 Global,因此没有数据复制、序列化开销。

示例:用 Global 实现一个简单索引并比较访问(思路示例)

假设有 ^User(id,"name") 和需要按 name 查询 id:

  • 直接按 id 找:SET id=123 WRITE ^User(id,"name") ------ 直接定位,最快。
  • 按 name 找 id:可以维护一个索引 global ^NameIndex(name,id)=1
    • 写入时同时更新 ^NameIndex(name,id)=1
    • 查询时 $ORDER(^NameIndex("Alice",id)) 找到对应 id,然后直接去 ^User(id,...) 读取。

这种做法把一个"按 name 查询"的昂贵操作转变为两个高效的键定位操作。

5. Globals 结构比页结构(Page)快太多:稀疏、有序、按键直接定位

传统数据库 I/O 模型:

sql 复制代码
读取一行 → 必须读整个数据页(8KB / 16KB)

IRIS 的 Global 模型:

sql 复制代码
只读需要的节点,不需要读整个页
键顺序天然可排序

优点:

MySQL/PG(页结构) IRIS Globals(键结构)
对某一行的读会触发整页 I/O 只读需要的节点
row format 解码 无需解码
NULL bitmap / tuple header 无额外的元数据负担
页分裂昂贵 键插入更局部化
索引 B-tree + 行指针 索引本身是 global(键 → 主键)

这是 IRIS 在点查、范围查、索引查方面普遍更快的核心原因。


6 . 索引本质上是 Global(稀疏多维数组),天然有序,遍历速度极快

MySQL/PG 的 B-tree 索引:

  • page split
  • tuple decode
  • pointer 跳转
  • buffer pool miss → page I/O

IRIS 的索引结构本质是:

sql 复制代码
^Index("lastname", "Zhang", 1001) = ""
^Index("lastname", "Zhang", 1033) = ""

特点:

  • 连续键顺序存放,范围扫描超快
  • 键按字节序排序,无需额外排序
  • 节点小,I/O 少
  • 直接定位,无行格式开销

典型查询:

sql 复制代码
SELECT * FROM Person WHERE lastname='Zhang'

在 IRIS 中转化为:

sql 复制代码
遍历 ^Index("lastname","Zhang",*)
对每个 id 直接取 ^Person(id,*)

比 MySQL/PG 少了至少 两层 跳转和格式解码。


7. IRIS 的执行路径极短:SQL 层非常薄,没有大量中间对象

Java MySQL 驱动访问路径:

sql 复制代码
Java → JDBC → SQL Parse → Plan → Executor → Row → Column → Java对象

IRIS 访问路径:

sql 复制代码
Java → JDBC → SQL → 直接取 global 节点(立即可用)

没有:

  • Row对象
  • Column对象
  • 字段解码成本
  • 元数据构建成本

对比:

操作 MySQL/PG 成本 IRIS 成本
取整数 解码、拷贝、对象包装 直接从 global 读取
取字符串 变长字段解析 已经按字符串存放
范围查询 B-tree page scan 直接键顺序遍历

8. 示例一:单条查询路径对比(IRIS vs MySQL/PostgreSQL)

MySQL/Postgres 查询一条记录的路径(非常多层)

sql 复制代码
SQL -> Parser -> Optimizer
    -> Buffer Pool -> Page(8KB/16KB)
        -> Page directory -> Slot -> Tuple
    -> MVCC Snapshot
    -> WAL/Redo consistency checks
    -> 返回结果

层级数 ≈ 7~12 层


IRIS 查找一条记录(几乎无中间层)

sql 复制代码
SQL -> Parser -> Optimizer
    -> 直接定位到 Global 节点
    -> 返回结果

层级数 ≈ 3 层


对比示例(读取某个用户 ID=123)

MySQL/PostgreSQL 内部做的事情:
sql 复制代码
1. 找索引页 B-tree
2. Buffer pool 是否命中?不命中则读磁盘
3. 索引页内二分查找定位 tuple id
4. 去数据页 (heap page) 找 tuple
5. 检查 MVCC(是否被删除?是否可见?)
6. 扫描 undo log 以还原 snapshot
7. 返回结果

→ 即使只有 1 行记录,也要经过多个 page、多次跳转、MVCC 判断。


IRIS 内部做的事情:

IRIS Orders 数据会这样存储在 Global:

sql 复制代码
^Orders(123) = "John|2024-02-03|PAID"

查找:

sql 复制代码
Get ^Orders(123)

就这么一句。

没有 page、没有 tuple、没有 undo、没有 MVCC snapshot。


性能差距示例

同样是查询 100 万条数据中的一条

项目 MySQL/PostgreSQL(B-tree) IRIS(Globals)
查找成本 log(N) 在 B-tree 中跳页 log(N) 但无 page,只是树节点
每层的代价 页命中/磁盘 IO 内存节点
一次查找路径 3~6 个 page 1~3 个节点
MVCC 必须检查可见性 无需检查
最终速度 ⭐ 30~800 微秒 ⭐ 1~20 微秒

IRIS 速度是 数量级 优势,因为中间层少到极致。

9 什么是 IRIS 的箭头语法(→)?

IRIS 独有的简写查询语法:

sql 复制代码
SELECT Name, Home.City -> Name
FROM Person

表示:

  • Home 是引用(类似外键)
  • → Name 表示自动"跳转"到关联对象的名称

它本质上不是 JOIN。

而是:

直接通过对象指针查找关联记录,属于一次 Global 多维树的直接定位

和传统数据库 JOIN 完全不同。


传统数据库 JOIN 在多表时的结构问题

传统数据库(MySQL/PostgreSQL/Oracle)JOIN 必须:

1. 扫描或索引查找 table A

2. 扫描或索引查找 table B

3. 构建临时 JOIN buffer / Hash table / Merge buffer

4. 比较 key

5. 输出结果

JOIN 越多:

  • 需要越多的中间结构
  • JOIN 顺序极其重要
  • 执行计划变复杂
  • 内存 buffer 越大
  • IO 越多
  • SQL 优化难度成倍增加

越多表 = 越慢


10. IRIS 的箭头语法为什么快?

因为 IRIS 底层不是基于表,也不是 JOIN。

IRIS 使用:

面向对象的引用结构 + 多维 Globals 树

查询关联数据 = 节点路径跳转(非常快)

一个箭头跳转(→)相当于:

  • 去对象的 OID 映射表查一次(O(log N))
  • 直接定位到对应的 Global 节点
  • 读取数据(几十~几百字节)

没有 JOIN、没有 buffer、没有排序、没有临时表。


🟦 直观对比:同样的 3 表查询

假设 3 个表:

  • Person
  • Address
  • Country

传统 SQL:

sql 复制代码
SELECT p.Name, a.City, c.Name
FROM Person p
JOIN Address a ON p.AddressID = a.ID
JOIN Country c ON a.CountryID = c.ID

需要 2 次 JOIN:

  • JOIN Person → Address
  • JOIN Address → Country

优化器要决定:

  • Hash join? Merge join? Nested loop?
  • 哪个表先?
  • 哪个表驱动?
  • 有没有索引?
  • 内存是否足够?

复杂,昂贵,容易退化。


🟢 IRIS 箭头语法:

sql 复制代码
SELECT Name, Address -> City, Address -> Country -> Name
FROM Person

解释:

  • Address -> City = 找 Address 关联对象,取 City 字段
  • Address -> Country -> Name = 连续跳转两层

这不是 JOIN。

而是:

步骤 IRIS 做的事情
1 获取 Person OID
2 跳到 Address OID(一次 Global 查找)
3 取 City
4 跳到 Country OID
5 取 Country Name

全部都是 O(log N) 节点级访问,没有 JOIN。


🔥 性能差距巨大

项目 传统数据库 JOIN IRIS 箭头语法
结构类型 表 + 行 + 页 对象引用 + 全局树节点
算法 JOIN(O(N logN) 或 worse) 直接定位(O(logN))
中间结果 大量临时表、哈希表 完全没有
CPU 很低
内存 JOIN buffer 几乎无
IO 要访问多个表的页 一个节点一个节点访问
多层深度 指数级变慢 几乎线性(跳一次节点)
SQL 复杂度 指数增加 简洁不变

当 join 超过 4~5 张表时:

  • MySQL/PostgreSQL 会非常吃力
  • IRIS 则基本无压力(只是多个 O(logN) 跳转)

1. 箭头语法基于"对象引用",不是基于 JOIN

所以跳转不依赖临时结构。

2. 箭头语法直接利用 IRIS 的 Global 多层树结构

存储结构天生适合多层引用。

3. 多表访问的成本是"节点跳转",而不是"多表 join"

成本随层数线性增长,而不是指数增长。

4. 箭头语法可以无限深度引用

传统数据库 JOIN 超过 7~10 层就难以优化。

5. 执行计划简单、可预测、稳定

不像 JOIN 可能因为统计信息变动突然退化。


🧪 示例:深度 4 层引用

传统 SQL:

sql 复制代码
SELECT p.Name, c.Name, r.Name, z.Name
FROM Person p
JOIN City c ON p.CityID = c.ID
JOIN Region r ON c.RegionID = r.ID
JOIN Zone z ON r.ZoneID = z.ID

IRIS 箭头语法:

sql 复制代码
SELECT Name,
       City -> Name,
       City -> Region -> Name,
       City -> Region -> Zone -> Name
FROM Person

传统数据库:

4 个 JOIN = 执行计划复杂、大量 IO、中间表、排序风险

IRIS:

4 次节点跳转 → 非常轻量


🎯 为什么 IRIS 箭头语法查询多表比传统 SQL 更快?

原因 解释
不是 JOIN IRIS 使用对象指针跳转,不生成任何临时 join 结构
不按"表 + 行 + 页"访问 IRIS 访问的是全局节点,粒度极小
多表 = 多次节点跳转 而不是 JOIN 复杂度增长
无 Hash/Merge/Nested-loop 开销 因为根本不需要
无排序 / 临时表 跳转 = O(logN) 数百字节 IO
执行计划更稳定 不受统计信息等因素影响
更适合复杂层级结构 深层引用比传统数据库 JOIN 快几个数量级

多张表复杂关系时,为什么 IRIS 使用 ObjectScript + Globals 的开发方式,能比传统数据库(MySQL/PostgreSQL)用 SQL Join 更高效、更简单。


11. 传统数据库:复杂关系 = 多表 Join = 性能瓶颈 & 开发复杂

在 MySQL/PostgreSQL 里,复杂数据关系通常写成:

sql 复制代码
SELECT o.id, o.total, c.name, a.street, a.city
FROM orders o
JOIN customers c ON o.customer_id = c.id
JOIN addresses a ON c.address_id = a.id
WHERE o.id = 1001;

数据库内部要做:

  • 解析 SQL
  • 构建执行计划
  • 访问多个页(page)
  • 在 B-tree 上查找多次
  • 做多个 Join(Nested Loop / Hash Join)
  • 从 buffer pool 取 page
  • 做 MVCC 快照一致性检查
  • 可能产生临时表

📌 即便字段是索引,也要走很多层:page → tuple → row → join → filter → return

IRIS:使用 Global(天然多维索引结构)可以直接定位值

假设我们有如下 Global 结构:

sql 复制代码
^Order(orderId) = $lb(customerId, total)
^Customer(customerId) = $lb(name, addressId)
^Address(addressId) = $lb(street, city)

三张表的关系其实在树结构中是已经拆好了。

🔥 IRIS 中读取复杂关系只需要:

sql 复制代码
SET order = ^Order(1001)
SET customer = ^Customer($LISTGET(order, 1))
SET address = ^Address($LISTGET(customer, 2))

WRITE "订单金额: ", $LISTGET(order, 2), !
WRITE "客户姓名: ", $LISTGET(customer, 1), !
WRITE "客户城市: ", $LISTGET(address, 2), !

📌 没有 Join

📌 没有 page lookup

📌 没有 tuple decode

📌 没有 MVCC

📌 直接通过节点路径取得数据

速度 = 树结构 O(logN) 定位 → 立即读出。


3. 性能差异举例(真实结构对比)

假设要获取订单 → 用户 → 地址完整信息

🔷 MySQL/PostgreSQL 的执行路径

sql 复制代码
SQL Parser
→ Optimizer
→ Join Plan (Hash Join)
→ B-tree lookup (orders)
→ B-tree lookup (customers)
→ B-tree lookup (addresses)
→ Construct result row
→ Return

SQL 越复杂,Join 越多,性能呈指数下降。


🔷 IRIS Globals 的执行路径

sql 复制代码
^Order → direct key lookup
^Customer → direct key lookup
^Address → direct key lookup
Return

无需优化器sql

无需 Join

无需 tuple decode

无需 page IO

无需 MVCC / WAL

树结构天然就是索引


4. 举例说明速度差异

假设 500 万订单、500 万客户、500 万地址。

MySQL 的 join 查询:

sql 复制代码
SELECT ... FROM orders
JOIN customers ...
JOIN address ...
WHERE orders.id = X;

执行:

  • 三次 B-tree 查找(每次可能访问多个 page)
  • Join 逻辑消耗 CPU
  • 需要构建 Row 格式
  • 需要 tuple 解码
  • 需要 MVCC 检查
  • 有 buffer pool miss 时还需磁盘 IO

耗时常见:3--20ms


IRIS Global 查找:

sql 复制代码
SET order = ^Order(X)
SET customer = ^Customer($LISTGET(order,1))
SET address = ^Address($LISTGET(customer,2))

执行:

  • 三次树节点直接读(通常在内存中)
  • 无 join、无 MVCC、无 page

耗时:0.05--0.2ms

👉 理论上快 20~100 倍

👉 这还是单线程,不用优化器


5. 为什么 IRIS 可以直接取值?

因为 Globals 不是传统数据库的"数据页 + 行 + 列"的结构

它是:

  • 稀疏多维数组
  • 树形结构(平衡 B-tree)
  • 每个节点就是 key/value
  • 天然支持多维索引

例如:

sql 复制代码
^Order(1001,"Customer","Name") = "张三"
^Order(1001,"Customer","City") = "上海"

你可以直接访问:

sql 复制代码
WRITE ^Order(1001,"Customer","City")

📌 你可以随意设计树节点结构,只取你要的路径

📌 不需要扫描行或构建 RowObject

📌 不需要访问多个 page

📌 没有冗余字段解码

传统数据库必须 select row → parse tuple → map column → join → output

IRIS 则是 一步直达节点


6. IRIS 多表复杂关系开发的优势总结

项目 传统 RDBMS(MySQL/PostgreSQL) IRIS(Globals + ObjectScript)
数据结构 表 & 行 & 页 多维树 Globals
多表查询 Join 是必需的 直接取节点,无需 Join
性能瓶颈 Join、page IO、MVCC 直接定位节点,无中间层
复杂业务逻辑 SQL 里难写 ObjectScript 对树操作非常简单
扩展性 修改 schema 成本高 Global 可随意添加新维度
维护成本 复杂 SQL 难维护 树结构天然表达关系
性能优化 索引、缓存、执行计划 Global = 天然索引结构

7. 最形象的比喻(特别精准)

MySQL/PostgreSQL:

像是你要找一份文件:

  1. 先到 A 档案柜(order)翻文件夹
  2. 再去 B 档案柜(customer)找对照
  3. 再去 C 档案柜(address)找地址
  4. 再把三个结果拼成 PDF 返回

耗时自然很高。


IRIS Globals:

所有数据都在一棵大树里,路径已经预先规划:

sql 复制代码
/Order/1001/Customer/Address

你只要顺着树拿值,不需要 Join 拼接。

就是 直接跳到精确坐标取出数据


总结(最核心一句话)

IRIS 在多表复杂查询时快,是因为 Global 把数据拆成多维树结构,使得跨表数据可以 O(logN) 直接定位,无需 SQL Join、无需访问 page、无需 MVCC,也无需解码 tuple。

相关推荐
M***Z2102 小时前
SQL中如何添加数据
数据库·sql
Croa-vo2 小时前
Tesla Spring 2026 Co-op 面经:CodeSignal真题解析与通关攻略
java·后端·spring
p***s912 小时前
MySQL的底层原理与架构
数据库·mysql·架构
n***78682 小时前
SpringCloud-持久层框架MyBatis Plus的使用与原理详解
spring·spring cloud·mybatis
C***u1762 小时前
【springboot】Spring 官方抛弃了 Java 8!新idea如何创建java8项目
java·spring boot·spring
CodeAmaz2 小时前
Spring 事务失效的 8 种常见场景总结
java·spring·事务失效
隔山打牛牛2 小时前
Spring 整合 MyBatis 深度详解(原理 + 实操 + 源码级解析)
java·spring·mybatis
b***62952 小时前
Redis 设置密码无效问题解决
数据库·redis·缓存
I***26152 小时前
Windows环境下安装Redis并设置Redis开机自启
数据库·windows·redis