首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >MySQL高级用法学习笔记

MySQL高级用法学习笔记

原创
作者头像
代码小李
发布2025-05-19 08:42:29
发布2025-05-19 08:42:29
5240
举报

MySQL高级用法学习笔记

MySQL作为一款广泛应用的关系型数据库,其高级用法能够显著提升数据处理能力和查询效率。本学习笔记将深入探讨窗口函数、复合查询和高级数据操作三大核心高级功能,帮助开发者掌握复杂数据分析与优化技巧。这些高级用法在处理报表生成、数据聚合和业务逻辑时尤为有用,能够减少应用程序层的数据处理负担,提高整体系统性能。

一、窗口函数详解

窗口函数是MySQL 8.0版本引入的革命性功能,它允许在保留原始数据行的同时,对数据集的特定窗口(窗口范围)执行复杂计算。与传统的GROUP BY不同,窗口函数不会减少结果集的行数,而是为每一行添加计算结果。

1. 窗口函数基本语法

窗口函数的基本语法结构如下:

代码语言:sql
复制
<窗口函数> ( <参数> ) OVER (
    [ PARTITION BY <分区表达式> ]
    [ ORDER BY <排序表达式> [ ASC | DESC ] ]
    [ frame_clause ]
)

核心组件

  • PARTITION BY:将结果集划分为独立的逻辑分区,函数在每个分区内独立计算。
  • ORDER BY:定义分区内部行的处理顺序,对于某些窗口函数(如ROW_NUMBER)是必须的。
  • frame Clause:精确控制窗口函数计算时包含的行集合,包括ROWS和RANGE两种类型。
2. 常用窗口函数及差异

MySQL支持多种窗口函数,其中排名函数的差异尤为关键:

排名函数对比

函数

排名方式

并列处理

后续序号

典型应用场景

ROW_NUMBER()

连续唯一

强制不同序号

连续递增

分页查询、唯一排名

RANK()

允许并列

相同排名

跳过空缺

比赛排名、允许跳跃

DENSE_RANK()

允许并列

相同排名

连续递增

成绩分级、不允许跳跃

例如,在工资排名场景中:

代码语言:sql
复制
-- ROW_NUMBER
SELECT name, salary, ROW_NUMBER() OVER (ORDER BY salary DESC) AS rank
FROM employees;

-- RANK
SELECT name, salary, RANK() OVER (ORDER BY salary DESC) AS rank
FROM employees;

-- DENSE_RANK
SELECT name, salary, DENSE_RANK() OVER (ORDER BY salary DESC) AS rank
FROM employees;

NTILE函数:将窗口内数据分为指定份数,适用于分组统计场景。

代码语言:sql
复制
SELECT name, salary, NTILE(4) OVER (ORDER BY salary DESC) AS quartile
FROM employees;
3. LAG与LEAD函数应用

LAG和LEAD函数用于获取窗口内前N行或后N行的值,特别适合时间序列分析和数据对比场景。

基本语法

代码语言:sql
复制
LAG(column_name, offset, default_value) OVER (PARTITION BY ... ORDER BY ...)
LEAD(column_name, offset, default_value) OVER (PARTITION BY ... ORDER BY ...)

应用场景示例

  1. 销售额环比分析SELECT product_id, sale_date, amount, LAG(amount) OVER (PARTITION BY product_id ORDER BY sale_date) AS prev_amount, (amount - LAG(amount) OVER (PARTITION BY product_id ORDER BY sale_date)) / LAG(amount) OVER (PARTITION BY product_id ORDER BY sale_date) * 100 AS growth_rate FROM sales WHERE LAG(amount) OVER (PARTITION BY product_id ORDER BY sale_date) IS NOT NULL ORDER BY product_id, sale_date;
  2. 库存预警SELECT product_id, stock_date, stock_level, LEAD(stock_level) OVER (PARTITION BY product_id ORDER BY stock_date) AS next_stock_level, stock_level - LEAD(stock_level) OVER (PARTITION BY product_id ORDER BY stock_date) AS stock_change FROM inventory ORDER BY product_id, stock_date;
  3. 股票价格波动SELECT stock_code, date, close_price, LAG(close_price) OVER (ORDER BY date) AS prev_close_price, (close_price - LAG(close_price) OVER (ORDER BY date)) / LAG(close_price) OVER (ORDER BY date) * 100 AS daily_change FROM stock_prices ORDER BY date;

关键点:LAG/LEAD函数支持多列分区(如PARTITION BY department, year)和动态窗口范围(如ROWS BETWEEN 2 PRECEDING AND 1 FOLLOWING),通过合理设置offset和default_value,可以处理边界情况和空值问题。

4. 窗口函数性能优化

窗口函数虽然功能强大,但其性能可能成为瓶颈,特别是在处理大数据集时。以下是关键优化策略:

索引优化:为PARTITION BYORDER BY的列创建合适索引,可显著提升性能。例如,一个优化案例显示,通过创建复合索引o_orderdate, o_custkey, o_totalprice,窗口函数查询性能提升了50倍。

代码语言:sql
复制
-- 优化前
SELECT * FROM (
    SELECT o.o_custkey, o.o_totalprice,
        RANK() OVER (PARTITION BY o.o_custkey ORDER BY o.o_totalprice) AS rn
    FROM orders AS o
    WHERE o.o_orderdate = '1996-06-20'
) AS A WHERE A.rn = 1;

-- 优化后
CREATE INDEX idx_order_date ON orders(o_orderdate, o_custkey, o_totalprice);

SELECT * FROM (
    SELECT o.o_custkey, o.o_totalprice,
        RANK() OVER (PARTITION BY o.o_custkey ORDER BY o.o_totalprice) AS rn
    FROM orders AS o
    WHERE o.o_orderdate = '1996-06-20'
) AS A WHERE A.rn = 1;

执行计划分析:使用EXPLAIN命令查看窗口函数的执行计划,识别性能瓶颈。重点关注type(访问类型)、key(实际使用的索引)和rows(预计扫描的行数)字段。

代码语言:sql
复制
EXPLAIN
SELECT d.name Department, a.name Employee, a.salary Salary
FROM (SELECT *, DENSE_RANK() OVER (PARTITION BY departmentId ORDER BY salary DESC) AS "rank"
      FROM employees) a
LEFT JOIN Department d ON a.departmentId = d.id
WHERE a.rank <= 3;

窗口范围控制:使用ROWSRANGE限制计算范围,避免不必要的全表扫描。例如:

代码语言:sql
复制
SELECT month, amount,
    SUM(amount) OVER (ORDER BY month ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) AS moving_sum
FROM sales;

覆盖索引:当查询仅需要索引中的列时,使用覆盖索引可避免回表操作,提高查询效率。例如:

代码语言:sql
复制
-- 创建覆盖索引
CREATE INDEX idx Department_salary ON employees(departmentId, salary, name);

-- 查询使用覆盖索引
SELECT departmentId, salary, name,
    RANK() OVER (PARTITION BY departmentId ORDER BY salary DESC) AS salary_rank
FROM employees;

二、复合查询技巧与优化

复合查询是处理复杂数据关系的核心技术,包括自关联、子查询和联合查询。合理使用这些技术可以简化查询逻辑,提高数据处理效率。

1. 自关联查询

自关联查询是同一张表关联自身,常用于处理树形结构和层级关系的数据。

基本语法

代码语言:sql
复制
SELECT a.column1, b.column2
FROM table_name a
JOIN table_name b ON a.id = b.parent_id;

多级递归查询:MySQL 8.0+支持使用WITH RECURSIVE实现多级递归查询,简化层级数据处理。

代码语言:sql
复制
WITH RECURSIVE SubDepartments AS (
    SELECT id, name, parent_id
    FROM departments
    WHERE parent_id = 1  -- 假设1是顶级部门的ID
    UNION ALL
    SELECT d.id, d.name, d.parent_id
    FROM departments d
    JOIN SubDepartments sd ON d.parent_id = sd.id
)
SELECT * FROM SubDepartments;

低版本MySQL递归查询:在8.0以下版本,可通过自定义函数实现递归查询,但效率较低。

代码语言:sql
复制
DELIMITER //
CREATE FUNCTION ` gettingSubordinates `(root_id BIGINT) RETURNS VARCHAR(1000)
BEGIN
    DECLARE k INT DEFAULT 0;
    DECLARE fid INT DEFAULT 1;
    DECLARE str VARCHAR(1000) DEFAULT '$';
    DECLARE cid VARCHAR(1000);
    SET cid = CAST(root_id AS CHAR);
    IF cid IS NOT NULL THEN
        SET str = CONCAT(str, ',', cid);
        SET k = k + 1;
    END IF;
    label:WHILE cid IS NOT NULL DO
        SELECT GROUP_CONCAT(id) INTO cid
        FROM employees
        WHERE parent_id IN (SELECT id FROM JSON_TABLE(str, '$[*]' COLUMNS (id INT PATH '$')) AS t);
        IF cid IS NOT NULL THEN
            SET str = CONCAT(str, ',', cid);
            SET k = k + 1;
        END IF;
    END label;
    RETURN str;
END //
DELIMITER ;

优化策略

  • 为关联字段(如manager_idparent_id)创建索引,避免全表扫描。
  • 使用临时表预处理数据,减少重复计算。
  • 在可能的情况下,优先使用覆盖索引,减少回表操作。
2. 子查询优化

子查询是嵌套在其他查询中的查询,虽然灵活但可能带来性能问题。

子查询类型与性能

  • 标量子查询:返回单个值,适用于WHERE或SELECT子句。
  • 多行子查询:返回多行数据,需搭配IN/ANY/ALL使用。
  • EXISTS/NOT EXISTS子查询:判断是否存在匹配记录,找到即停止。

性能优化策略

EXISTS vs IN性能对比:当子查询表数据量极大时,EXISTS性能通常优于IN,因为它逐行匹配,找到即返回,而IN需先生成完整子查询结果集。

代码语言:sql
复制
-- EXISTS查询(性能更优)
SELECT * FROM t_customer tcustomer
WHERE EXISTS(
    SELECT 1 FROM t_order torder
    WHERE tcustomer.customer_no = torder.customer_no
);

-- IN查询(性能较差)
SELECT * FROM t_customer tcustomer
WHERE tcustomer.customer_no IN (
    SELECT customer_no FROM t_order
);

子查询转换为JOIN:在某些情况下,JOIN操作比子查询更高效,特别是对大表。

代码语言:sql
复制
-- 子查询版本
SELECT * FROM products
WHERE category_id IN (
    SELECT category_id FROM categories
    WHERE type = 'Electronics'
);

-- JOIN版本(性能更优)
SELECT p.* FROM products p
JOIN categories c ON p.category_id = c.category_id
WHERE c.type = 'Electronics';

避免子查询陷阱

  • 当子查询返回多行时,使用IN而不是=。
  • 避免在子查询中使用SELECT *,仅选择必要的列。
  • 使用EXPLAIN分析子查询性能,识别潜在的全表扫描。

分页查询优化:使用主键记录分页,避免偏移量大的OFFSET操作。

代码语言:sql
复制
-- 慢速分页查询
SELECT * FROM employees
ORDER BY id LIMIT 100000, 10;

-- 优化后的分页查询
SELECT * FROM employees
WHERE id > 100000
LIMIT 10;
3. 联合查询(UNION vs UNION ALL)

联合查询用于合并多个SELECT语句的结果集,但UNION和UNION ALL在处理方式上有本质区别。

性能差异

  • UNION:自动去除重复行,并对结果集进行排序,性能较低。
  • UNION ALL:保留所有行(包括重复数据),不执行排序,性能显著更高。

使用场景

  • 当需要去重且数据量较小时,使用UNION。
  • 当数据量大且允许重复时,优先使用UNION ALL。

示例代码

代码语言:sql
复制
-- 使用UNION去重
SELECT salesman_id FROM salesman
UNION
SELECT salesman_id FROM orders
ORDER BY salesman_id;

-- 使用UNION ALL保留所有行
SELECT salesman_id FROM salesman
UNION ALL
SELECT salesman_id FROM orders
ORDER BY salesman_id;

联合查询注意事项

  • 列数必须严格一致,否则会报错。
  • 对应列的数据类型需兼容,必要时使用显式转换(如CONVERT)。
  • 联合查询的列名以第一个SELECT语句的列名为准。

性能优化建议

  • 为子查询添加适当的索引,减少全表扫描。
  • 限制结果集大小,子查询返回的数据量越小越好。
  • 在可能的情况下,使用UNION ALL替代UNION。

三、JSON处理高级技巧

MySQL 5.7开始支持JSON数据类型,8.0版本进一步增强了JSON处理能力。合理利用JSON功能可以简化半结构化数据的管理。

1. JSON查询与操作函数

MySQL提供了丰富的JSON函数,用于提取、修改和验证JSON数据。

常用JSON函数

代码语言:sql
复制
-- 提取JSON值
SELECT JSON_EXTRACT('{"name": "张三", "age": 30}', '$.name') AS name;  -- 返回 "张三"

-- 提取数组元素
SELECT JSON_EXTRACT('["a", "b", "c"]', '$[1]') AS element;  -- 返回 "b"

-- 检查JSON是否包含特定值
SELECT JSON_CONTAINS('{"store": {"book": {"title": "MySQL指南"}}}', '"MySQL指南"');  -- 返回 1

-- 获取JSON长度
SELECT JSON_LENGTH('{"items": [{"id": 1}, {"id": 2}]}', '$.items[*]') AS length;  -- 返回 2

动态键名处理:当JSON键名包含特殊字符或数字时,可使用双引号包裹键名。

代码语言:sql
复制
-- 查询字符串类型的数字键
SELECT JSON_EXTRACT(price, "$.sku \"45453\".algorithm") AS algorithm
FROM price
WHERE id = 159540;
2. JSON字段索引优化

对JSON字段进行索引可以显著提升查询性能,但需要遵循特定方法。

虚拟列索引:通过创建虚拟列提取JSON值,然后对虚拟列创建索引。

代码语言:sql
复制
-- 创建虚拟列
ALTER TABLE employees ADD COLUMN json_name VARCHAR(100) GENERATED ALWAYS AS (json_column->>"$.name") VIRTUAL;

-- 创建索引
CREATE INDEX idx_json_name ON employees(json_name);

-- 查询使用索引
EXPLAIN
SELECT * FROM employees
WHERE json_name = 'John';

多值索引:MySQL 8.0.17+支持为JSON数组创建多值索引。

代码语言:sql
复制
-- 创建多值索引
ALTER TABLE table_name ADD INDEX idx attrs_arr_key(
    (CAST(`business_attr`->"$[*].attrArrKey" AS CHAR(32) ARRAY))
);

-- 查询使用多值索引
SELECT * FROM table_name
WHERE JSON-overlaps(`business_attr`->"$[*].attrArrKey", CAST('"1000"' AS JSON));

JSON_TABLE函数:将JSON数据转换为关系型表格,便于后续SQL处理。

代码语言:sql
复制
-- 基本使用
SELECT o.id, jt.product, jt.price
FROM orders o
JOIN JSON_TABLE(
    o.order_data,
    '$.items[*]' COLUMNS (
        product VARCHAR(50) PATH '$.product',
        price DECIMAL(10,2) PATH '$.price'
    )
) AS jt ON TRUE;

-- 嵌套JSON处理
SELECT p.id, jt1.name AS customer_name, jt2.product AS item_product
FROM people p
JOIN JSON_TABLE(
    p.info,
    '$' COLUMNS (
        name VARCHAR(50) PATH '$.name',
        age INT PATH '$.age'
    )
) AS jt1 ON TRUE
JOIN JSON_TABLE(
    p.info,
    '$.items[*]' COLUMNS (
        product VARCHAR(50) PATH '$.product'
    )
) AS jt2 ON TRUE;

JSON TABLE与聚合结合:将JSON数组数据展开后进行聚合计算。

代码语言:sql
复制
-- 统计订单总金额
SELECT o.id, SUM(jt.price) AS total_price
FROM orders o
JOIN JSON_TABLE(
    o.order_data,
    '$.items[*]' COLUMNS (
        price DECIMAL(10,2) PATH '$.price'
    )
) AS jt ON TRUE
GROUP BY o.id;
3. JSON字段更新与事务

在事务中操作JSON字段需要特别注意数据一致性。

JSON字段更新

代码语言:sql
复制
-- 修改JSON字段下的指定键值
UPDATE price
SET price = JSON_SET(price, "$.attr \"1280\".price_old", 300)
WHERE id IN (171314);

JSON与事务结合

代码语言:sql
复制
START TRANSACTION;

-- 更新JSON字段
UPDATE employees
SET attributes = JSON_SET(attributes, "$.status", "active")
WHERE id = 1001;

-- 插入相关记录
INSERT INTO employee_log (employee_id, action, action_time)
VALUES (1001, 'status updated to active', NOW());

COMMIT;

四、索引优化高级技巧

索引是MySQL性能优化的关键,但合理设计和使用索引需要深入理解其原理。

1. 复合索引最左前缀原则

复合索引必须遵循最左前缀原则,即MySQL会从索引的最左列开始匹配条件。

示例

代码语言:sql
复制
-- 创建复合索引
CREATE INDEX idx_name_age_city ON user(name, age, city);

-- 有效使用
SELECT * FROM user WHERE name = '张三';  -- 使用索引(name)
SELECT * FROM user WHERE name = '张三' AND age = 25;  -- 使用索引(name, age)
SELECT * FROM user WHERE name = '张三' AND age = 25 AND city = '北京';  -- 使用完整索引

-- 无效使用(无法命中索引)
SELECT * FROM user WHERE age = 25;  -- 跳过了索引的最左列name
SELECT * FROM user WHERE name = '张三' AND city = '北京';  -- 中间跳过了age列

优化建议

  • 根据高频查询条件设计复合索引顺序。
  • 避免在索引列上进行函数操作或类型转换。
  • 使用覆盖索引减少回表操作。
2. 降序索引优化

MySQL支持创建降序索引,适用于需要按降序排序的查询场景。

创建语法

代码语言:sql
复制
-- 创建降序索引
CREATE INDEX idx created_desc ON log_entries (created_at DESC);

-- 创建复合降序索引
CREATE INDEX idx_date_status ON orders (create_date DESC, status);

应用场景

  • 优化ORDER BY create_date DESC, status等查询。
  • 减少排序开销,提高查询效率。

注意事项

  • 降序索引在复合索引中需明确指定排序方向。
  • 索引维护成本会略高于普通索引,需权衡使用。
3. 索引碎片清理

长期使用后,索引可能出现碎片,影响查询性能。

碎片清理方法

  • OPTIMIZE TABLE:重建表和索引,整理碎片,但会锁表,适合小表。
  • 在线工具:如Percona Toolkit的pt-online-schema-change,可无锁重建表。
  • 定期维护:根据业务情况,每周或每月执行一次碎片整理。

示例

代码语言:sql
复制
-- 清理索引碎片
OPTIMIZE TABLE employees;

-- 使用pt-online-schema-change在线重建表
pt-online-schema-change --execute D=your_database,t=your_table

五、高级事务处理

事务是确保数据库操作原子性和一致性的机制,掌握高级事务处理技巧对于构建高并发系统至关重要。

1. 事务隔离级别

MySQL支持四种标准事务隔离级别,每种级别对并发问题的处理方式不同。

隔离级别对比

隔离级别

脏读

不可重复读

幻读

性能

适用场景

读未提交

✅ 允许

✅ 允许

✅ 允许

统计类操作(需谨慎)

读已提交

❌ 不允许

✅ 允许

✅ 允许

中高

大多数业务场景

可重复读

❌ 不允许

❌ 不允许

✅ 允许

需要事务内数据一致性的场景

串行化

❌ 不允许

❌ 不允许

❌ 不允许

严格要求数据一致性的场景

设置隔离级别

代码语言:sql
复制
-- 全局设置
SET GLOBAL TRANSACTION ISOLATION LEVEL READ COMMITTED;

-- 会话级设置
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;

-- 单事务设置
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;

MySQL的特殊处理:InnoDB引擎在可重复读级别下通过Next-Key Locks机制避免幻读,这是MySQL的优化特性。

2. 保存点与部分回滚

保存点允许在事务中创建临时检查点,实现部分回滚。

基本语法

代码语言:sql
复制
START TRANSACTION;

-- 执行一些操作
INSERT INTO users (name, email) VALUES ('Alice', 'alice@example.com');
INSERT INTO orders (user_id, amount) VALUES (1, 100);

-- 设置保存点
SAVEPOINT my_savepoint;

-- 执行更多操作
INSERT INTO payments (order_id, amount) VALUES (1, 100);

-- 假设这里发生错误,回滚到保存点
ROLLBACK TO my_savepoint;

-- 提交事务
COMMIT;

应用场景

  • 复杂事务处理中需要部分回滚。
  • 错误处理场景,避免整个事务失败。
  • 并发控制,确保数据一致性。

注意事项

  • 保存点仅适用于InnoDB等支持事务的存储引擎。
  • 保存点名称在当前事务中必须唯一。
  • 回滚到保存点后,事务仍然处于活动状态。
3. 锁机制与并发控制

MySQL提供了多种锁机制,用于控制并发操作。

共享锁与排他锁

  • 共享锁(S锁):允许其他事务读取但不允许写入。
  • 排他锁(X锁):阻止其他事务读取或写入。

锁范围控制:使用覆盖索引减少FOR UPDATE锁定范围。

代码语言:sql
复制
-- 仅锁定必要的行
SELECT id, name FROM employees
WHERE department_id = 10
ORDER BY salary DESC
LIMIT 10 FOR UPDATE OF employees;

-- 锁定整个表(慎用)
LOCK TABLES employees WRITE;

死锁诊断:通过SHOW ENGINE INNODB STATUS查看死锁日志,分析死锁原因。

代码语言:sql
复制
-- 查看死锁信息
SHOW ENGINE INNODB STATUS;

乐观锁:通过版本号或时间戳实现,避免长事务中的锁竞争。

代码语言:sql
复制
-- 使用版本号实现乐观锁
UPDATE employees
SET salary = salary * 1.1, version = version + 1
WHERE id = 1001 AND version = 1;

六、高级用法综合应用

1. 窗口函数与JSON结合

将窗口函数与JSON处理结合,可以处理复杂的半结构化数据分析。

代码语言:sql
复制
-- 查询每个产品类别下JSON数组中的价格趋势
SELECT category_id, product,
    LAG(JSON_EXTRACT(product_data, '$.price'), 1, 0) OVER (
        PARTITION BY category_id ORDER BY update_time
    ) AS prev_price,
    JSON_EXTRACT(product_data, '$.price') AS current_price,
    (JSON_EXTRACT(product_data, '$.price') - LAG(JSON_EXTRACT(product_data, '$.price'), 1, 0) OVER (
        PARTITION BY category_id ORDER BY update_time
    )) / LAG(JSON_EXTRACT(product_data, '$.price'), 1, 0) OVER (
        PARTITION BY category_id ORDER BY update_time
    ) * 100 AS price_change百分比
FROM products
WHERE JSON_EXTRACT(product_data, '$.price') IS NOT NULL;
2. 复合查询与事务结合

在事务中执行复合查询,确保操作的一致性和完整性。

代码语言:sql
复制
START TRANSACTION;

-- 查询并锁定符合条件的订单
SELECT order_id, customer_id, amount
FROM orders
WHERE status = 'pending'
ORDER BY created_time DESC
LIMIT 10 FOR UPDATE SKIP LOCKED;

-- 更新订单状态
UPDATE orders
SET status = 'processing'
WHERE order_id IN (1001, 1002, 1003);

-- 创建保存点
SAVEPOINT order Processing;

-- 插入处理记录
INSERT INTO order log (order_id, action, action_time)
VALUES (1001, 'processing started', NOW());

-- 可能的错误处理
-- ROLLBACK TO SAVEPOINT order Processing;

COMMIT;
3. 窗口函数与自关联结合

结合窗口函数和自关联查询,可以实现复杂的层级数据分析。

代码语言:sql
复制
-- 查询每个部门员工的工资排名及与上级的工资差异
WITH RECURSIVE Department Hierarchy AS (
    SELECT id, name, manager_id, salary,
        ROW_NUMBER() OVER (PARTITION BY department_id ORDER BY salary DESC) AS salary_rank
    FROM employees
    WHERE manager_id IS NULL
    UNION ALL
    SELECT e.id, e.name, e.manager_id, e.salary,
        ROW_NUMBER() OVER (PARTITION BY e.department_id ORDER BY e.salary DESC) AS salary_rank
    FROM employees e
    JOIN Department Hierarchy dh ON e经理_id = dh.id
)
SELECT dh.id, dh.name, dh salary_rank,
    dh salary - LAG(dh salary) OVER (
        PARTITION BY dh.department_id ORDER BY dh.salary DESC
    ) AS diff_with_previous
FROM Department Hierarchy dh
ORDER BY dh.department_id, dh salary_rank;

七、总结与最佳实践

窗口函数:提供了强大的数据分析能力,适用于排名、分组计算和趋势分析等场景。使用时需注意索引优化和窗口范围控制,以避免性能问题。

复合查询:包括自关联、子查询和联合查询,能够处理复杂的数据关系。自关联适用于树形结构数据,子查询需谨慎使用以免影响性能,联合查询则需注意列兼容性和使用UNION ALL以提高效率。

JSON处理:MySQL的JSON功能支持半结构化数据的存储和查询。通过JSON_TABLE函数可将JSON数据转换为关系型表格,使用虚拟列索引可优化JSON字段查询性能。

索引优化:复合索引遵循最左前缀原则,降序索引可优化特定排序场景。定期清理索引碎片,避免过度索引,以保持数据库高效运行。

事务处理:合理选择事务隔离级别,使用保存点实现部分回滚,通过锁机制控制并发访问。了解死锁原因并采取预防措施,确保事务安全。

最佳实践

  • 窗口函数:优先为PARTITION BY和ORDER BY的列创建索引,使用EXPLAIN分析执行计划。
  • 子查询:在大数据集场景下,优先使用EXISTS替代IN,考虑将子查询转换为JOIN。
  • JSON处理:对频繁查询的JSON键创建虚拟列索引,使用JSON_TABLE处理复杂JSON结构。
  • 事务设计:保持事务简短,减少锁持有时间,必要时使用保存点。
  • 性能监控:定期分析慢查询日志,使用SHOW ENGINE INNODB STATUS诊断死锁问题。

通过深入理解并合理应用这些高级功能,开发者可以构建更高效、更灵活的MySQL查询,满足复杂业务场景的数据处理需求。在实际应用中,应根据具体业务场景和数据规模,选择最适合的查询技术和优化策略,以实现最佳性能。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • MySQL高级用法学习笔记
    • 一、窗口函数详解
      • 1. 窗口函数基本语法
      • 2. 常用窗口函数及差异
      • 3. LAG与LEAD函数应用
      • 4. 窗口函数性能优化
    • 二、复合查询技巧与优化
      • 1. 自关联查询
      • 2. 子查询优化
      • 3. 联合查询(UNION vs UNION ALL)
    • 三、JSON处理高级技巧
      • 1. JSON查询与操作函数
      • 2. JSON字段索引优化
      • 3. JSON字段更新与事务
    • 四、索引优化高级技巧
      • 1. 复合索引最左前缀原则
      • 2. 降序索引优化
      • 3. 索引碎片清理
    • 五、高级事务处理
      • 1. 事务隔离级别
      • 2. 保存点与部分回滚
      • 3. 锁机制与并发控制
    • 六、高级用法综合应用
      • 1. 窗口函数与JSON结合
      • 2. 复合查询与事务结合
      • 3. 窗口函数与自关联结合
    • 七、总结与最佳实践
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档