MySQL优化示例 1:关联查询

示例(优化前)

SELECT
    COUNT(*) AS count,
    dl.province_name
FROM
    device d
    JOIN user_device_rel udr ON d.device_id = udr.device_id
    JOIN device_location_from_app dl ON d.device_id = dl.device_id
WHERE
    d.category_id != 1
    AND province_name IS NOT NULL 
    AND province_name != '' 
GROUP BY
    dl.province_name 
ORDER BY
    count DESC;

示例(优化方法1,MySQL5.7)

优化思路
  • 提前过滤数据:使用子查询在连接表之前先对数据进行筛选,减少参与连接的数据量。
  • 索引优化:为参与 JOIN 和 WHERE条件的列创建合适的索引,加快查询速度。
SELECT
    COUNT(*) AS count,
    dl.province_name
FROM
    (SELECT device_id FROM device WHERE category_id != 1) d
    JOIN user_device_rel udr ON d.device_id = udr.device_id
    JOIN (SELECT device_id, province_name FROM device_location WHERE province_name IS NOT NULL AND province_name != '') dl ON d.device_id = dl.device_id
GROUP BY
    dl.province_name
ORDER BY
    count DESC;

示例(优化方法1,MySQL8.0及以上)

优化思路
  • 提前过滤数据:使用 WITH 子句(CTE,公共表表达式)在连接表之前先对数据进行筛选,减少参与连接的数据量。
  • 索引优化:为参与 JOIN 和 WHERE条件的列创建合适的索引,加快查询速度。
版本要求说明

从 MySQL 8.0 版本开始,MySQL 正式支持公共表表达式(CTE),这意味着你可以使用 WITH 关键字来创建 CTE。而在 MySQL 8.0 之前的版本,比如 MySQL 5.x 系列,是不支持 WITH 语法的。

WITH filtered_device AS (
   SELECT device_id
    FROM device
    WHERE category_id != 1
),
filtered_location AS (
    SELECT device_id, province_name
    FROM device_location
    WHERE province_name IS NOT NULL AND province_name != ''
)
SELECT
    COUNT(*) AS count,
    dl.province_name
FROM
    filtered_device d
    JOIN user_device_rel udr ON d.device_id = udr.device_id
    JOIN filtered_location dl ON d.device_id = dl.device_id
GROUP BY
    dl.province_name
ORDER BY
    count DESC;

知识点

在 SQL 中,WITH 关键字用于创建公共表表达式(Common Table Expressions,CTE)。CTE 是一种临时命名的结果集,它存在于单个 SQL 语句的执行范围内,可在该语句中被多次引用。下面为你详细解析 WITH 关键字及其使用场景和优势。

基本语法
WITH cte_name (column1, column2, ...) AS (
    -- CTE 的查询语句
    SELECT column1, column2, ...
    FROM table_name
    WHERE condition
)
-- 主查询语句,使用 CTE
SELECT *
FROM cte_name
WHERE another_condition;
  • cte_name:CTE 的名称,用于在主查询中引用该临时结果集。
  • (column1, column2, …):可选参数,用于指定 CTE 结果集中列的名称。如果省略,将使用子查询中列的名称。
  • AS:用于分隔 CTE 名称和子查询。
  • (SELECT …):CTE的子查询,用于生成临时结果集。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值