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

相关推荐
倔强的石头_11 小时前
《Kingbase护城河》——猎捕慢查询:执行计划的微观解析与索引调优实战
数据库
SelectDB13 小时前
Apache Doris Python UDF:让 SQL 直接调用 Python 生态,支撑 Agent 时代复杂业务逻辑
大数据·数据库·python
jiayou642 天前
KingbaseES 表级与列级加密完全指南
数据库·后端
GBASE2 天前
G术时刻 |GBase 8s数据库事务并发控制之封锁技术介绍(下)
数据库
xiezhr3 天前
逛GitHub发现了一款免费的带AI功能的数据库管理工具
数据库·ai编程·dba
唐青枫4 天前
MySQL JSON 实战详解:从存储、查询、更新到 JSON_TABLE 与索引
sql·mysql
吃糖的小孩4 天前
给 QQ AI 机器人设计“可控记忆”:会话摘要、手动长期记忆与角色卡边界
数据库
笃行3505 天前
金仓数据库数据安全双防线:静态存储加密与传输加密实战
数据库
笃行3505 天前
金仓数据库物理备份实战:sys_rman 全流程演练与误覆盖抢救
数据库
笃行3505 天前
金仓数据库逻辑备份实战:从全库导出到 Schema 替换的完整闭环
数据库