SQL更新语句性能调优技巧_避免对索引列执行函数操作

对索引列使用函数会导致索引失效,因破坏B+树有序性;应将函数移至等号右侧或改用范围查询,如WHERE name = UPPER('john')或WHERE created_at >= '2024-01-01' AND created_at < '2024-01-02'。WHERE 条件里对索引列用函数会直接让索引失效MySQL、PostgreSQL、SQL Server 都一样:WHERE UPPER(name) = 'JOHN' 或 WHERE DATE(created_at) = '2024-01-01' 这类写法,即使 name 或 created_at 有索引,优化器也大概率放弃使用。因为函数改变了原始值的有序性,B+ 树无法做范围跳查。实操建议:把函数移到等号右边:用 WHERE name = UPPER('john') 替代 UPPER(name) = 'JOHN'(前提是大小写不敏感 collation)日期范围改用闭区间:用 WHERE created_at >= '2024-01-01' AND created_at 替代 <code>DATE(created_at) = '2024-01-01'实在要函数转换,考虑生成列 + 索引:PostgreSQL 支持 CREATE INDEX ON t ((UPPER(name)));MySQL 5.7+ 可建函数索引列 ALTER TABLE t ADD COLUMN name_upper VARCHAR(64) STORED AS (UPPER(name)),再给该列加索引UPDATE 语句中 SET 子句对索引列赋值可能触发额外索引维护比如 UPDATE users SET status = 'active', updated_at = NOW() WHERE id = 123,如果 updated_at 是二级索引的一部分(比如复合索引 (status, updated_at)),每次更新都会导致该索引页分裂或重排,尤其在高并发写场景下明显拖慢性能。实操建议:避免在 SET 中无谓更新索引列:确认字段值是否真有变化,可用 WHERE status != 'active' AND id = 123 提前过滤把高频更新字段和低频查询字段拆到不同索引中:别把 updated_at 和常用于 WHERE 的 status 绑死在一个复合索引里对时间戳字段,优先用 CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP 自动更新,减少 SQL 层显式赋值WHERE 条件含隐式类型转换也会绕过索引典型错误:WHERE user_id = '123',而 user_id 是 INT 类型。MySQL 会把所有 user_id 值转成字符串比对,索引失效;PostgreSQL 则直接报错或拒绝隐式转换(取决于配置)。 唱鸭 音乐创作全流程的AI自动作曲工具,集 AI 辅助作词、AI 自动作曲、编曲、混音于一体

相关推荐
C137的本贾尼8 分钟前
【实战】分析一张真实业务表的 InnoDB 存储结构
java·大数据·数据库
huangdong_9 分钟前
京东整店商品图片视频批量下载技术:从商品列表到自动分类
开发语言·python·音视频
超梦dasgg9 分钟前
亿级数据 不停服务平滑迁移(生产环境实战方案)
java·数据库
j_xxx404_14 分钟前
MySQL数据库基础硬核解析:从 C/S 网络服务到磁盘文件与存储引擎
linux·运维·服务器·开发语言·数据库·mysql·ai
糖果店的幽灵15 分钟前
Spring AI 从入门到精通-ChatClient你与 AI 对话的终极武器
人工智能·python·spring
我是大猴子16 分钟前
死锁,慢sql排查,mysql死锁
数据库·sql
海鸥-w18 分钟前
用python (fastapi)做项目第二天实现新闻列表和新闻详情接口
开发语言·python·fastapi
Cloud_Shy61819 分钟前
解读《Effective Python 3rd Edition》:从练气到老魔(第四章 Item 25 - 26)
开发语言·人工智能·经验分享·笔记·python·学习方法
Minxinbb19 分钟前
TDSQL for MySQL部署选型
数据库·dba
C137的本贾尼21 分钟前
【实战】实现一个带事务与索引的命令行图书借阅系统
数据库·microsoft·oracle