SQL 调优实战:跨表排序性能提升之路

SQL 调优实战:跨表排序性能提升之路

在数据库操作中,跨表查询与排序是常见但性能易出瓶颈的场景。本文将结合实际案例,分享一次跨表排序 SQL 的调优过程,通过优化前后的对比,展现性能提升的显著效果。

一、调优背景

在业务系统中,我们需要从多个关联表中查询有效商品 SKU 信息,并按商品生命周期的修改时间倒序排列。原 SQL 语句在执行时耗时较长,达到了 1 秒,随着数据量增长,性能问题愈发突出,因此需要进行针对性优化。

二、优化前 SQL 分析

1. 原 SQL 语句

复制代码
SELECT
        a.id AS subSkuId,
        a.CODE AS subSkuCode,
        a.NAME AS subSkuName,
        c.lifecycle,
        c.id AS lifecycle_id,
        d.id AS category_id 
FROM
        product_sku a
        LEFT JOIN sku_tag_relation b ON a.id = b.sku_id
        AND b.deleted = 0
        LEFT JOIN sku_lifecycle c ON a.id = c.sku_id
        AND c.deleted = 0
        LEFT JOIN product_category d ON a.category_id = d.id
        AND d.deleted = 0
        LEFT JOIN (
        SELECT
                approval_no,
                approval_status,
                lifecycle_id,
                lock_type,
                batch_code,
                ROW_NUMBER() OVER ( PARTITION BY lifecycle_id ORDER BY gmt_modified DESC ) AS rn
        FROM
                sku_lifecycle_change
        WHERE
        deleted = 0) e ON c.id = e.lifecycle_id 
WHERE
        a.deleted = 0
        AND a.sku_status ="VALID"
        AND b.tag_code IN (1000,1003,1005) 
GROUP BY
        a.id 
ORDER BY
        c.gmt_modified DESC
        LIMIT 10

线上耗时:1s

在测试环境复现,也是执行要1s,确实是慢sql

2. 性能瓶颈分析

  • 表连接顺序问题 :原 SQL 以product_sku表为主表进行左连接,后续关联多个表,会先扫描大量product_sku数据,再进行过滤和关联,数据处理量较大。

  • 排序效率低 :在最后对c.gmt_modified进行排序时,由于是基于多表关联后的临时表排序,没法走索引,数据量较大,排序耗时久。

三、优化方案与实施

1. 优化思路

  • 调整表连接顺序 :将排序字段所在的sku_lifecycle表作为主表,通过内连接关联product_sku表,减少初始扫描的数据量。

  • 优化连接类型 :将部分左连接调整为内连接,在过滤条件中提前筛选有效数据,缩小结果集范围。

2. 优化后 SQL 语句

复制代码
SELECT
        a.id AS subSkuId,
        a.CODE AS subSkuCode,
        a.NAME AS subSkuName,
        c.lifecycle,
        c.id AS lifecycle_id,
        d.id AS category_id
        FROM
        sku_lifecycle c
        INNER JOIN product_sku a ON c.sku_id = a.id
        AND a.deleted = 0
        LEFT JOIN sku_tag_relation b ON a.id = b.sku_id
        AND b.deleted = 0
        LEFT JOIN product_category d ON a.category_id = d.id
        AND d.deleted = 0
        LEFT JOIN (
        SELECT
                approval_no,
                approval_status,
                lifecycle_id,
                lock_type,
                batch_code,
                ROW_NUMBER() OVER ( PARTITION BY lifecycle_id ORDER BY gmt_modified DESC ) AS rn
        FROM
                sku_lifecycle_change
        WHERE
                deleted = 0
        ) e ON c.id = e.lifecycle_id 
WHERE
        c.deleted = 0
        AND a.sku_status = "VALID"
        AND b.tag_code IN ( 1000, 1003, 1005 ) 
GROUP BY
        a.id 
ORDER BY
        c.gmt_modified DESC
        LIMIT 10

3. 优化点说明

  • 主表调整 :以sku_lifecycle作为主表,通过内连接直接关联有效product_sku数据,排序的话根据sku_lifecycle表走索引排序

四、调优效果对比

指标 优化前 优化后 提升比例
执行时间 1 秒 0.09 秒 约 91%

通过本次调优,SQL 语句的执行时间从 1 秒缩短至 0.09 秒,性能提升显著,有效解决了原查询的性能瓶颈,提升了系统响应速度。

五、总结与启示

1、排序字段尽量放到驱动表,不然用临时表排序不走索引的话,即使limit 10,也会慢在排序上面

通过本次实战,我们深刻体会到 SQL 调优对系统性能的关键作用,在日常开发中,应注重编写高效的 SQL 语句,不断提升系统的整体性能。

相关推荐
qq21084629538 小时前
【数据库】TDengine 清理旧数据
数据库·oracle·tdengine
j_xxx404_8 小时前
MySQL表操作硬核解析:从 CREATE TABLE 到磁盘文件、ALTER TABLE 与 DDL 风险
运维·服务器·数据库·c++·mysql·adb·ai
持敬chijing8 小时前
Web渗透之SQL注入-二次注入(Second-Order SQL Injection)
sql·安全·web安全·网络安全·网络攻击模型·安全威胁分析
数据库小学妹8 小时前
PostgreSQL迁移到国产数据库怎么做?评估、改造、上线全流程实操指南
数据库·经验分享·postgresql·dba
x***r1519 小时前
Redis Desktop Manager 0.8.8 安装教程(Windows redis-desktop-manager-0.8.8.384详细步骤)
数据库·windows·redis
initialize13069 小时前
Postgresql(Oracle兼容) 到Oracle19.9字符语义
数据库·oracle
稷下元歌9 小时前
七天学会plc 加机器视觉完整笔记:S7-1200 数据类型、存储区与寻址方式(I/Q/M/DB 详解)。
网络·数据库·笔记
潮起鲸落入海9 小时前
mysql 5.x源码安装
数据库·mysql
phltxy10 小时前
MCP 从协议到 Spring AI 实战
人工智能·spring·oracle
睡不醒男孩03082310 小时前
第一篇:多云与多模态时代的企业级数据库云管理平台(DBaaS)选型指南
数据库·clup·中启乘数