在数据库业务场景中,DISTINCT是实现数据去重的常用关键字,但传统执行模式下,其常伴随全表扫描、排序、哈希去重等高耗时操作,尤其在数据量庞大、查询列可被筛选条件固定的场景中,性能瓶颈尤为突出,直接影响业务响应效率。金仓数据库聚焦DISTINCT语句性能痛点,研发内核层面自动优化技术,通过精准的 SQL 逻辑改写,将低效去重操作转化为高效查询,同时深度融合编译原理中的常量传递、谓词传递技术,实现查询性能的跨越式提升,为国产数据库优化器技术提供新范式。
一、DISTINCT 语句的传统性能痛点
DISTINCT语句的核心作用是剔除查询结果中的重复数据,但其传统执行逻辑存在天然缺陷。以基础查询SELECT DISTINCT a,b FROM s1;为例,传统执行流程需先对s1表进行全表扫描,获取所有数据后执行全局排序,再通过排序结果完成去重操作。
这种模式在数据量激增时,会面临双重性能损耗:一方面全表扫描会消耗大量 I/O 资源,另一方面排序与哈希去重属于高 CPU 开销操作,当查询列可通过WHERE条件、关联条件等固定为常量时,传统方案仍会执行全量扫描与去重流程,冗余操作进一步放大性能问题,成为业务系统的性能桎梏。
二、金仓数据库 DISTINCT 优化的核心技术路径
金仓数据库摒弃传统DISTINCT执行逻辑,构建两层核心优化体系,同时融入常量传递、谓词传递技术,实现精准、高效的 SQL 改写,从根源上解决性能瓶颈。
(一)路径一:DISTINCT 转 GROUP BY,借力分组优化能力
金仓数据库通过内核识别机制,在保证语义完全等价的前提下,自动将DISTINCT语句改写为GROUP BY语句,借助GROUP BY的键值裁剪、并行执行能力,降低去重开销。
优化示例
- 优化前 SQL:
SELECT DISTINCT a,b FROM s1;
- 优化后内核改写 SQL:
SELECT a,b FROM s1 GROUP BY a,b;
改写后,查询不再对a、b整体进行全量去重,而是利用主键键值消除冗余分组,同时启用并行查询能力,减少无效数据处理。实测数据显示,未优化前查询耗时 464ms,开启DISTINCT转GROUP BY优化后,耗时降至 249ms,性能提升近一倍。
(二)路径二:常量固定场景下,LIMIT 1 替代去重操作
金仓数据库深度融合编译原理中的常量传递与谓词传递技术,精准判断目标列是否被固定为常量。当查询列可通过WHERE条件、关联条件等约束为常量时,结果集最多仅存一条有效数据,无需执行完整去重或分组操作,此时内核自动用LIMIT 1替代DISTINCT或GROUP BY,实现 “找到即返回” 的高效查询。
1. 简单常量约束场景
- 优化前 SQL:
SELECT DISTINCT a,b FROM s1 WHERE a=1 AND b=1;
- 优化后内核改写 SQL:
SELECT a,b FROM s1 WHERE a=1 AND b=1 LIMIT 1;
传统方案需扫描所有满足a=1、b=1的记录后再去重,金仓数据库通过常量传递技术识别a、b均为固定常量,判定结果集唯一,直接改写为LIMIT 1查询。实测优化前耗时 30ms,优化后仅 0.03ms,性能提升近千倍。
2. 关联查询常量传递场景
常量传递技术同样适用于多表关联场景,通过谓词传递推导关联列常量属性。
- 优化前 SQL
SELECT s1.a,s2.b FROM s1 INNER JOIN s2 ON s1.a=s2.b AND s1.a=5 GROUP BY s1.a,s2.b;
- 优化后内核改写 SQL:
- SELECT s1.a,s2.b FROM s1 INNER JOIN s2 ON s1.a=s2.b AND s1.a=5 LIMIT 1
优化前需筛选、关联后再分组去重,耗时 12ms;金仓数据库通过谓词传递,由s1.a=5推导s2.b=5,判定结果集唯一,改写后无需分组去重,耗时降至 0.08ms,大幅减少无效数据扫描与计算。