SQL Join 中函数使用对性能的影响与优化方法

在日常开发中,经常会遇到这样的场景:

需要在 大小写不敏感格式化字段 的情况下进行表关联。

如果在 JOINWHERE 中直接使用函数,往往会带来严重的性能问题。

本文用一个新的示例来说明问题和优化方法。


一、问题场景

假设我们有两张表:

  • 用户表 user_info

    diff 复制代码
    user_id   | username
    ----------+------------
    1         | Alice
    2         | Bob
    3         | Charlie
  • 订单表 order_info

    yaml 复制代码
    order_id  | buyer_name
    ----------+------------
    1001      | alice
    1002      | BOB
    1003      | dave

我们希望根据用户名和买家名称进行关联(忽略大小写)。


原始写法(低效)

sql 复制代码
SELECT o.order_id, u.user_id, u.username
FROM order_info o
LEFT JOIN user_info u
    ON LOWER(o.buyer_name) = LOWER(u.username);

问题

  • LOWER() 包裹了字段,导致数据库无法使用索引。
  • 每一行都要执行函数运算,性能下降。

二、优化方法

1. 子查询提前计算

通过子查询生成派生列,再进行关联。

sql 复制代码
SELECT o.order_id, u.user_id, u.username
FROM (
    SELECT order_id, buyer_name, LOWER(buyer_name) AS buyer_name_lower
    FROM order_info
) o
LEFT JOIN (
    SELECT user_id, username, LOWER(username) AS username_lower
    FROM user_info
) u
    ON o.buyer_name_lower = u.username_lower;

优点

  • 避免在 JOIN 时重复调用函数。
  • 优化器有机会物化子查询并建立临时索引。

2. 建立函数索引(推荐)

如果这种需求非常频繁,可以在表上建立函数索引。

PostgreSQL 示例

scss 复制代码
CREATE INDEX idx_username_lower ON user_info(LOWER(username));
CREATE INDEX idx_buyer_name_lower ON order_info(LOWER(buyer_name));

之后即使写:

sql 复制代码
SELECT ...
FROM order_info o
LEFT JOIN user_info u
    ON LOWER(o.buyer_name) = LOWER(u.username);

数据库也能走索引,性能大幅提升。


3. 数据入库时统一格式

如果业务允许,可以在入库时统一转为小写,避免查询时做转换。

sql 复制代码
INSERT INTO user_info (user_id, username)
VALUES (1, LOWER('Alice'));

这样关联时直接比较即可:

ini 复制代码
ON o.buyer_name = u.username

三、总结

  • JOINWHERE 中直接使用函数,会 导致索引失效,影响性能。

  • 优化方法

    1. 子查询提前计算,避免在关联时重复调用函数;
    2. 建立函数索引(或虚拟列索引);
    3. 入库时统一数据格式,彻底消除函数依赖。

📌 记忆要点

  • 函数写在 JOIN → 慢
  • 子查询提前算 → 好
  • 函数索引 / 数据规范化 → 最优解
相关推荐
AAA@峥15 小时前
CentOS7 源码编译安装 MySQL5.7|SQL 基础操作 + 备份恢复完整实战
运维·数据库·sql·centos
IvorySQL1 天前
PG 日报|修复高 IO 并发场景,解决预读机制耗尽本地缓冲区缺陷
数据库·人工智能·sql·postgresql·区块链
qq_150841991 天前
SQL的insert和update二合一指令
java·数据库·sql
宸津-代码粉碎机1 天前
SQL 深度精讲|IN 与 NOT IN 用法、底层原理、NULL 致命坑、性能优化(实战干货)
大数据·数据库·sql·spring·搜索引擎·性能优化
破碎的南瓜2 天前
sqli--sql注入过关笔记(1,2,3,4,5,9)
数据库·笔记·sql
Csvn2 天前
📊 SQL 入门 Day 10:递归 CTE — 破解无限层级查询的终极武器
后端·sql
Database_Cool_2 天前
企业级多模态分析计算引擎选型:首选 AnalyticDB MySQL 向量 + SQL + 实时一体化方案
数据库·sql·mysql
洵有兮2 天前
sql注入通关笔记
数据库·笔记·sql·sql注入
sbjdhjd2 天前
SQL 注入零基础详解:原理、手工注入流程与 Sqli-Labs 靶场实战1~5关和第9关思路
数据库·sql·计算机网络·web安全·网络安全·网络攻击模型·安全架构