news 2026/6/15 19:36:59

写了 5 年 SQL,才发现可以用 (a, b) > (x, y) 这种神仙写法!

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
写了 5 年 SQL,才发现可以用 (a, b) > (x, y) 这种神仙写法!
关注我们,设为星标,每天7:30不见不散,每日java干货分享

你有一张日志表,主键是联合主键(category_id, seq_id)。现在你需要查询“某个分类下的某个序列号”之后的所有记录。
普通青年的写法(逻辑噩梦):

SELECT * FROM logs WHERE category_id > 100 OR (category_id = 100 AND seq_id > 500);

这种写法不仅难看,而且括号套括号,一旦字段变成 3 个(比如加上timestamp),逻辑复杂度呈指数级上升,写错概率极大。
文艺青年的写法(行比较):

SELECT * FROM logs WHERE (category_id, seq_id) > (100, 500);

优雅!极致的优雅!这种写法不仅代码短,而且语义清晰,MySQL 和 PostgreSQL 都完美支持。


1. 核心原理:元组的“字典序”比较

所谓“行比较”,就是把多个字段打包成一个元组 (Tuple)进行比较。

数据库在比较(A, B) > (X, Y)时,遵循的是字典序 (Lexicographical Order)规则,逻辑如下:

  1. 1.先比第一位:如果A > X,则整个表达式为 True(直接结束,不看 B)。

  2. 2.如果第一位相等:如果A = X,则继续比较第二位,判断B > Y

  3. 3.如果第一位小于:如果A < X,则整个表达式为 False。

这和我们查英文字典的逻辑一模一样:apple为什么排在banana前面?先比abapple为什么排在apricot前面?因为a=a,p=p, 但p < r


2. 核心实战场景:高性能“游标分页” (Keyset Pagination)

这是行比较价值最高的场景,没有之一。

背景:
当表数据量达到千万级时,传统的LIMIT 10 OFFSET 1000000会导致数据库扫描 100 万行废弃数据,性能极差。
我们通常推荐使用“游标分页” (Seek Method),即记录上一页最后一条数据的排序值,下一页从这里开始查。

痛点:
很多时候,单一字段(如create_time)无法保证唯一性(可能有两条记录时间戳完全一样)。所以我们通常用(create_time, id)组成的联合键来排序,确保唯一性。

传统写法 (痛苦面具):
我们要查2024-12-01 12:00:00(ID=888) 之后的数据:

SELECT * FROM orders WHERE create_time > '2024-12-01 12:00:00' OR (create_time = '2024-12-01 12:00:00' AND id > 888) ORDER BY create_time, id LIMIT 10;

行比较写法 (丝般顺滑):

SELECT * FROM orders WHERE (create_time, id) > ('2024-12-01 12:00:00', 888) ORDER BY create_time, id LIMIT 10;

这一行代码,完美解决了“时间相同看 ID,时间不同看时间”的复杂逻辑。


3. 实战场景二:复合主键的批量查询 (IN 列表)

背景:
你有一张关联表user_roles,主键是(user_id, role_id)
你需要批量删除或查询一批特定的用户-角色关系。

普通写法:

SELECT * FROM user_roles WHERE (user_id = 1 AND role_id = 10) OR (user_id = 1 AND role_id = 20) OR (user_id = 2 AND role_id = 15);

写 100 个这样的条件,SQL 解析器都要累哭了。

行比较写法:

SELECT * FROM user_roles WHERE (user_id, role_id) IN ( (1, 10), (1, 20), (2, 15) );

清晰明了,且大多数数据库优化器能对这种语法进行优化。


4. 实战场景三:版本号/区间重叠检测

背景:
软件版本号通常由(Major, Minor, Patch)组成,例如2.5.1
你想找出所有版本号高于2.5.1的记录。

行比较写法:

SELECT * FROM software_versions WHERE (major, minor, patch) > (2, 5, 1);

这比拼接字符串CONCAT(major, '.', minor...)或者复杂的OR逻辑要靠谱得多(字符串比较会有 '10' < '2' 的陷阱,而数字元组比较不会)。


5. 注意事项与索引优化

虽好用,但有坑,特别是索引

  1. 1.索引利用 (MySQL 5.7+):
    在 MySQL 5.7 之前,(a, b) > (x, y)这种写法无法利用(a, b)的联合索引,会导致全表扫描。
    但在 MySQL 5.7 及 8.0+ 中,优化器已经足够智能,可以完美利用联合索引进行 Range Scan。

  2. 2.方向一致性:
    如果你的联合索引是(a ASC, b ASC),那么(a, b) > (x, y)可以走索引。
    但如果你的查询逻辑非常怪异,比如a > x AND b < y,这就不能用行比较简写了。

  3. 3.NULL 值陷阱:
    如果字段中包含NULL,行比较的结果可能是UNKNOWN。在用于主键或非空列(如分页场景)时最安全。


6. 总结

行比较 (Row Comparison)是 SQL 语言中被严重低估的“语法糖”。

  • • 它将复杂的布尔逻辑转化为直观的数学元组对比

  • • 它是实现高性能深度分页的最佳拍档。

  • • 它让你的 SQL 代码看起来更像资深工程师的手笔。

下次遇到多字段联合比较时,试试(a, b) > (x, y),你会爱上这种简洁。

推荐阅读 点击标题可跳转

50个Java代码示例:全面掌握Lambda表达式与Stream API

16 个 Java 代码“痛点”大改造:“一般写法” VS “高级写法”终极对决,看完代码质量飙升!

为什么高级 Java 开发工程师喜爱用策略模式

精选Java代码片段:覆盖10个常见编程场景的更优写法

提升Java代码可靠性:5个异常处理最佳实践

为什么大佬的代码中几乎看不到 if-else,因为他们都用这个...

还在 Service 里疯狂注入其他 Service?你早就该用 Spring 的事件机制了

看完本文有收获?请转发分享给更多人

关注「java干货」加星标,提升java技能

❤️给个「推荐 」,是最大的支持❤️

.cls-1{fill:#001e36;}.cls-2{fill:#31a8ff;}

.cls-1{fill:#001e36;}.cls-2{fill:#31a8ff;}

.cls-1{fill:#001e36;}.cls-2{fill:#31a8ff;}

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/15 19:34:19

nvm终极清理术:彻底解决磁盘爆满的5个技巧

你的电脑是不是经常弹出"磁盘空间不足"的警告&#xff1f;作为Node.js开发者&#xff0c;nvm让版本切换变得轻松&#xff0c;但长期使用后积累的垃圾文件却让系统越来越卡顿。本文带你掌握nvm性能优化的核心技巧&#xff0c;一键释放宝贵磁盘空间。 【免费下载链接】…

作者头像 李华
网站建设 2026/6/13 10:05:35

终极日语转换神器:WanaKana让你的日语学习效率翻倍!

终极日语转换神器&#xff1a;WanaKana让你的日语学习效率翻倍&#xff01; 【免费下载链接】WanaKana Javascript library for detecting and transforming between Hiragana, Katakana, and Romaji 项目地址: https://gitcode.com/gh_mirrors/wa/WanaKana 还在为日语假…

作者头像 李华
网站建设 2026/6/6 8:33:43

Ender3V2S1 3D打印机固件终极配置与调平指南

想要让您的Ender3V2S1打印机发挥最佳性能&#xff1f;本指南将带您从零开始&#xff0c;掌握固件配置与自动调平的核心技巧&#xff0c;让3D打印变得简单高效。 【免费下载链接】Ender3V2S1 This is optimized firmware for Ender3 V2/S1 3D printers. 项目地址: https://git…

作者头像 李华
网站建设 2026/6/13 21:42:12

imgproxy技术深度解析:企业级图像处理解决方案的实战指南

imgproxy技术深度解析&#xff1a;企业级图像处理解决方案的实战指南 【免费下载链接】imgproxy Fast and secure standalone server for resizing and converting remote images 项目地址: https://gitcode.com/gh_mirrors/img/imgproxy 在当今数字化时代&#xff0c;图…

作者头像 李华
网站建设 2026/6/15 18:17:33

Cleopatra:终极文本分析与挖掘工具完整指南

你是否曾经面对海量文本数据感到无从下手&#xff1f;&#x1f635; 想要从用户评论、新闻报道、社交媒体内容中提取有价值的信息&#xff0c;却苦于没有合适的工具&#xff1f;Cleopatra正是为解决这些问题而生的终极解决方案&#xff01; 【免费下载链接】cleopatra Admin Da…

作者头像 李华