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

相关推荐
+VX:Fegn08953 小时前
计算机毕业设计|基于springboot + vue蛋糕店管理系统(源码+数据库+文档)
前端·数据库·vue.js·spring boot·课程设计
哈__5 小时前
KES-Operator重塑Kubernetes环境下的KES数据库集群管理
数据库·kubernetes·operator·kes
IvorySQL7 小时前
IvorySQL 5.6 发布:PG 18.6 内核升级,沙盒即开即用
数据库·人工智能·postgresql
bbq粉刷匠7 小时前
触发器(下):事务与锁、binlog 一致性与替代方案
sql
CNSSIRD数据库7 小时前
中国企业环境信用数据库2003-2026
大数据·数据库·数据分析·论文笔记
fd32008 小时前
达梦数据库更新统计信息后仍走旧执行计划解决方案
数据库
华章酱8 小时前
MySQL幻读是怎么出现的
数据库·mysql·幻读
浅念-9 小时前
Redis基础详解:单线程模型、String与Hash数据结构
服务器·数据库·redis·sql·mysql·nosql数据库·nosql
updayday8549 小时前
离职域账号状态变更与Ping64操作记录核对
大数据·网络·数据库·安全·智能路由器
Nturmoils9 小时前
只恢复一张表,别把整个库都还回去
数据库