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 语句,不断提升系统的整体性能。

相关推荐
Irene19912 小时前
数据发散(Data Spreading)详解(附:示例 数据发散最大值是笛卡尔乘积)
数据库
a9511416422 小时前
c++如何解析二进制协议中的可选字段读取逻辑及其反序列化【详解】
jvm·数据库·python
weixin_580614002 小时前
golang如何实现时间格式化_golang时间格式化方法详解
jvm·数据库·python
forEverPlume2 小时前
c++怎么利用std--span实现在不拷贝数据的前提下解析大规模文件【进阶】
jvm·数据库·python
FinTech老王2 小时前
逻辑删除不等于物理销毁:KingbaseES敏感数据标记与销毁实操指南
数据库·安全·oracle
HHHHH1010HHHHH2 小时前
Tailwind CSS如何快速定义固定宽高比_使用aspect-square实现CSS正方形
jvm·数据库·python
梦想的旅途22 小时前
解构自动化办公新思路:实现外部群聊能力的深度集成与交互
java·数据库·rpa
m0_515098422 小时前
c++怎么获取文件的Inode节点信息_stat结构体深度解析【详解】
jvm·数据库·python
m0_674294642 小时前
HTML怎么限制输入字符数_HTML input maxlength属性用法【详解】
jvm·数据库·python