当前位置: 首页 > news >正文

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的子查询,用于生成临时结果集。

相关文章:

  • vue3-tree-org创建组织架构图简单案例分享
  • scala基础
  • 剧本杀APP系统开发,市场发展前景
  • 计算机毕业设计SpringBoot+Vue.js基于工程教育认证的计算机课程管理平台(源码+文档+PPT+讲解)
  • 搭建一个私有NuGet服务器
  • 【AI深度学习基础】NumPy完全指南进阶篇:核心功能与工程实践(含完整代码)
  • OpenCV计算摄影学(10)将一组不同曝光的图像合并成一张高动态范围(HDR)图像的实现类cv::MergeDebevec
  • GEE学习笔记 28:基于Google Earth Engine的Landsat8缨帽变换土壤指数反演——亮度、绿度与湿度分量的提取
  • 白话React第九章React 前沿技术与企业级应用实战
  • 跨平台文件互传工具
  • python-leetcode-斐波那契数
  • FastAPI系列:如何配置跨域访问(CORS)
  • 10. 作者去换监控源了,不知道什么原因,zabbix自定义监控无法获取
  • 微服务面试题及原理
  • 一周一个Unity小游戏2D反弹球游戏 - 移动的弹板(鼠标版)
  • React面试葵花宝典之二
  • 年后 总结
  • 【PCIe 总线及设备入门学习专栏 1.2 -- 访问 PCIe 设备过程】
  • 实现遍历Windows所有字体的基本属性
  • 从黑暗到光明:FPC让盲人辅助眼镜成为视障者的生活明灯!【新立电子】
  • 网站301定向/一元友情链接平台
  • 政府网站建设以什么为宗旨/百度竞价收费标准
  • 设计师 推荐 网站/网站宣传方法
  • 做专题页的背景网站/合肥网站关键词排名
  • 恶意点击别人的网站/网站运营优化培训
  • 网站标题第一个词/百度推广页面投放