SQL查询高级应用学习:从基础到实战的系统学习路径
一、高级查询技术
(一)窗口函数
窗口函数是SQL高级查询中非常重要的内容,它允许在查询结果中进行更复杂的计算,而无需对数据进行分组或聚合,从而能够保留每一行的详细信息。
1. 基本语法
窗口函数的基本语法如下:
<窗口函数> OVER (PARTITION BY <列> ORDER BY <列>)
其中,<窗口函数>
可以是SUM
、AVG
、COUNT
、MAX
、MIN
等聚合函数,也可以是ROW_NUMBER()
、RANK()
、DENSE_RANK()
等排名函数。PARTITION BY
用于将数据划分为多个分区,每个分区内的数据可以独立进行计算;ORDER BY
用于指定分区内的排序规则。
2. 应用场景
窗口函数在数据分析中有着广泛的应用,以下是一些常见的应用场景:
-
累计求和:计算每一行的累计金额或数量。例如,在销售数据中,计算每个客户的累计销售额。
SELECT customer_id, order_date, order_amount, SUM(order_amount) OVER (PARTITION BY customer_id ORDER BY order_date) AS cumulative_amount FROM orders;
-
移动平均:计算某个时间段内的平均值。例如,计算过去7天的平均销售额。
SELECT order_date, order_amount, AVG(order_amount) OVER (ORDER BY order_date ROWS BETWEEN 6 PRECEDING AND CURRENT ROW) AS moving_average FROM orders;
-
排名:使用
ROW_NUMBER()
、RANK()
和DENSE_RANK()
对数据进行排名。ROW_NUMBER()
会为每一行分配一个唯一的序号,RANK()
和DENSE_RANK()
则会处理并列排名的情况。SELECT employee_id, salary, RANK() OVER (ORDER BY salary DESC) AS rank, DENSE_RANK() OVER (ORDER BY salary DESC) AS dense_rank FROM employees;
3. 示例
假设我们有一个订单表orders
,包含以下字段:
order_id
:订单编号customer_id
:客户编号order_date
:订单日期order_amount
:订单金额
我们可以使用窗口函数来计算每个客户的累计订单金额:
SELECT
order_id,
customer_id,
order_date,
order_amount,
SUM(order_amount) OVER (PARTITION BY customer_id ORDER BY order_date) AS cumulative_amount
FROM
orders;
这个查询的结果将包含每一行的订单信息以及到目前为止该客户的累计订单金额。
(二)公共表表达式(CTE)
公共表表达式(CTE)是一种临时的结果集,可以在查询中被多次引用。它使用WITH
语句定义,语法如下:
WITH <CTE名称> AS (<子查询>)
SELECT ...
CTE的主要用途是简化复杂的查询,使查询更加清晰易读。它还可以用于递归查询,处理树状结构数据。
1. 基本语法
CTE的基本语法如下:
WITH CTE_name AS (
<子查询>
)
SELECT ...
FROM CTE_name;
其中,CTE_name
是CTE的名称,<子查询>
是定义CTE的查询语句。CTE定义后,可以在主查询中像使用普通表一样使用CTE。
2. 应用场景
-
简化复杂查询:将复杂的子查询分解为多个简单的CTE,便于理解和维护。
WITH sales_summary AS ( SELECT customer_id, SUM(order_amount) AS total_sales FROM orders GROUP BY customer_id ) SELECT customer_id, total_sales, CASE WHEN total_sales > 1000 THEN 'High Value' ELSE 'Low Value' END AS customer_category FROM sales_summary;
-
递归查询:处理树状结构数据,如组织架构、用户推荐关系等。
WITH RECURSIVE employee_hierarchy AS ( SELECT employee_id, manager_id, 1 AS level FROM employees WHERE manager_id IS NULL UNION ALL SELECT e.employee_id, e.manager_id, eh.level + 1 FROM employees e JOIN employee_hierarchy eh ON e.manager_id = eh.employee_id ) SELECT employee_id, manager_id, level FROM employee_hierarchy;
3. 示例
假设我们有一个员工表employees
,包含以下字段:
employee_id
:员工编号manager_id
:上级领导编号name
:员工姓名
我们可以使用CTE来查询每个员工的层级关系:
WITH RECURSIVE employee_hierarchy AS (
SELECT
employee_id,
manager_id,
1 AS level
FROM
employees
WHERE
manager_id IS NULL
UNION ALL
SELECT
e.employee_id,
e.manager_id,
eh.level + 1
FROM
employees e
JOIN
employee_hierarchy eh ON e.manager_id = eh.employee_id
)
SELECT
employee_id,
manager_id,
level
FROM
employee_hierarchy;
这个查询的结果将展示每个员工的层级关系,从顶层领导开始,逐级向下展开。
(三)递归查询
递归查询是处理树状结构数据的一种强大工具。它通过递归调用自身,逐步展开层级关系,直到满足终止条件。
1. 基本语法
递归查询的基本语法如下:
WITH RECURSIVE CTE_name AS (
<初始查询>
UNION ALL
<递归查询>
)
SELECT ...
FROM CTE_name;
其中,<初始查询>
用于定义递归的起点,<递归查询>
用于定义递归的逻辑。
2. 应用场景
- 组织架构:查询员工的层级关系。
- 用户推荐关系:查询用户的推荐链。
- 文件系统:查询目录的层级结构。
3. 示例
假设我们有一个文件系统表file_system
,包含以下字段:
file_id
:文件编号parent_id
:父文件夹编号file_name
:文件名
我们可以使用递归查询来查询文件的层级结构:
WITH RECURSIVE file_hierarchy AS (
SELECT
file_id,
parent_id,
file_name,
1 AS level
FROM
file_system
WHERE
parent_id IS NULL
UNION ALL
SELECT
fs.file_id,
fs.parent_id,
fs.file_name,
fh.level + 1
FROM
file_system fs
JOIN
file_hierarchy fh ON fs.parent_id = fh.file_id
)
SELECT
file_id,
parent_id,
file_name,
level
FROM
file_hierarchy;
这个查询的结果将展示文件的层级结构,从根目录开始,逐级展开。
(四)子查询优化
子查询是SQL查询中常见的结构,但不当使用可能会导致性能问题。优化子查询的关键在于理解其执行计划,并选择更高效的方式来实现相同的目标。
1. 子查询的类型
-
相关子查询:子查询依赖于外部查询的值。
SELECT employee_id, salary FROM employees e WHERE salary > ( SELECT AVG(salary) FROM employees WHERE department_id = e.department_id );
-
派生表:子查询作为临时表使用。
SELECT e.employee_id, e.salary, d.avg_salary FROM employees e JOIN (SELECT department_id, AVG(salary) AS avg_salary FROM employees GROUP BY department_id) d ON e.department_id = d.department_id;
2. 优化技巧
-
避免相关子查询:相关子查询可能会导致性能问题,因为每次外部查询的行都会触发一次子查询的执行。可以通过将相关子查询转换为连接查询来优化。
SELECT e.employee_id, e.salary, d.avg_salary FROM employees e JOIN (SELECT department_id, AVG(salary) AS avg_salary FROM employees GROUP BY department_id) d ON e.department_id = d.department_id;
-
使用派生表:将子查询的结果存储为派生表,可以减少重复计算。
SELECT e.employee_id, e.salary, d.avg_salary FROM employees e JOIN (SELECT department_id, AVG(salary) AS avg_salary FROM employees GROUP BY department_id) d ON e.department_id = d.department_id;
3. 示例
假设我们有一个员工表employees
,包含以下字段:
employee_id
:员工编号department_id
:部门编号salary
:员工薪资
我们可以使用优化后的查询来查找薪资高于部门平均薪资的员工:
SELECT
e.employee_id,
e.salary,
d.avg_salary
FROM
employees e
JOIN
(SELECT
department_id,
AVG(salary) AS avg_salary
FROM
employees
GROUP BY
department_id) d
ON
e.department_id = d.department_id
WHERE
e.salary > d.avg_salary;
这个查询通过将相关子查询转换为连接查询,提高了查询性能。
(五)复杂聚合与分组
SQL中的聚合和分组是数据处理中常见的操作,但复杂的业务需求可能需要更高级的分组技术。
1. 基本语法
聚合和分组的基本语法如下:
SELECT
<列>,
<聚合函数>(<列>)
FROM
<表>
GROUP BY
<列>;
其中,<聚合函数>
可以是SUM
、AVG
、COUNT
、MAX
、MIN
等。
2. 高级分组技术
-
GROUPING SETS
:允许在单个查询中生成多个分组。SELECT department_id, job_id, SUM(salary) AS total_salary FROM employees GROUP BY GROUPING SETS ( (department_id), (job_id), () );
这个查询将生成三个分组:按
department_id
分组、按job_id
分组以及全局汇总。 -
CUBE
:生成所有可能的分组组合。SELECT department_id, job_id, SUM(salary) AS total_salary FROM employees GROUP BY CUBE (department_id, job_id);
这个查询将生成所有可能的分组组合,包括
department_id
和job_id
的所有组合。 -
ROLLUP
:生成分组的层次结构。SELECT department_id, job_id, SUM(salary) AS total_salary FROM employees GROUP BY ROLLUP (department_id, job_id);
这个查询将生成分组的层次结构,包括
department_id
的汇总和job_id
的汇总。
3. 示例
假设我们有一个员工表employees
,包含以下字段:
employee_id
:员工编号department_id
:部门编号job_id
:职位编号salary
:员工薪资
我们可以使用GROUPING SETS
来生成多个分组:
SELECT
department_id,
job_id,
SUM(salary) AS total_salary
FROM
employees
GROUP BY
GROUPING SETS (
(department_id),
(job_id),
()
);
这个查询的结果将包含按department_id
分组的汇总、按job_id
分组的汇总以及全局汇总。
二、高级数据操作
(一)事务管理
事务是数据库中用于保证数据一致性的基本单元。它确保一系列操作要么全部成功,要么全部失败。
1. 事务的ACID原则
- 原子性(Atomicity):事务中的所有操作要么全部完成,要么全部不完成。
- 一致性(Consistency):事务执行前后,数据库的状态必须保持一致。
- 隔离性(Isolation):并发执行的事务之间不会相互干扰。
- 持久性(Durability):事务一旦提交,其结果将永久保存。
2. 事务的使用场景
-
数据更新:在更新数据时,使用事务确保操作的完整性。
BEGIN; UPDATE employees SET salary = salary * 1.1 WHERE department_id = 1; COMMIT;
-
多表操作:在涉及多个表的操作中,使用事务确保一致性。
BEGIN; INSERT INTO orders (customer_id, order_amount) VALUES (1, 100); INSERT INTO order_items (order_id, product_id, quantity) VALUES (1, 1, 10); COMMIT;
3. 事务的隔离级别
- READ UNCOMMITTED:最低的隔离级别,允许读取未提交的数据。
- READ COMMITTED:默认的隔离级别,只允许读取已提交的数据。
- REPEATABLE READ:保证在同一个事务中,多次读取同一数据的结果是一致的。
- SERIALIZABLE:最高的隔离级别,保证事务的串行执行。
4. 示例
假设我们有一个订单表orders
和订单详情表order_items
,我们需要在插入订单时同时插入订单详情:
BEGIN;
INSERT INTO orders (customer_id, order_amount)
VALUES (1, 100);
INSERT INTO order_items (order_id, product_id, quantity)
VALUES (1, 1, 10);
COMMIT;
这个事务确保了订单和订单详情的插入操作要么全部成功,要么全部失败。
(二)存储过程与触发器
存储过程和触发器是数据库中用于封装复杂逻辑和自动执行操作的工具。
1. 存储过程
存储过程是一组预编译的SQL语句,可以接受参数并返回结果。
(1)创建存储过程
CREATE PROCEDURE GetEmployeeDetails (
IN employee_id INT
)
BEGIN
SELECT
employee_id,
name,
salary
FROM
employees
WHERE
employee_id = employee_id;
END;
(2)调用存储过程
CALL GetEmployeeDetails(1);
(3)存储过程的优点
- 封装复杂逻辑:将复杂的SQL语句封装在一个存储过程中,便于维护和重用。
- 提高性能:存储过程是预编译的,执行效率更高。
- 安全性:可以通过存储过程限制用户对底层数据的直接访问。
2. 触发器
触发器是一种特殊的存储过程,它在特定的数据库操作(如插入、更新、删除)发生时自动执行。
(1)创建触发器
CREATE TRIGGER UpdateEmployeeSalary
AFTER UPDATE ON employees
FOR EACH ROW
BEGIN
IF NEW.salary > 10000 THEN
INSERT INTO audit_log (employee_id, action, old_salary, new_salary)
VALUES (NEW.employee_id, 'UPDATE', OLD.salary, NEW.salary);
END IF;
END;
(2)触发器的使用场景
- 数据审核:记录数据的变更历史。
- 自动更新:在某些字段更新时自动更新其他字段。
- 数据完整性:确保数据满足特定的约束条件。
3. 示例
假设我们有一个员工表employees
和一个审计日志表audit_log
,我们需要在员工薪资更新时记录变更历史:
CREATE TRIGGER UpdateEmployeeSalary
AFTER UPDATE ON employees
FOR EACH ROW
BEGIN
IF NEW.salary > 10000 THEN
INSERT INTO audit_log (employee_id, action, old_salary, new_salary)
VALUES (NEW.employee_id, 'UPDATE', OLD.salary, NEW.salary);
END IF;
END;
这个触发器将在员工薪资更新时自动记录变更历史。
(三)索引设计与优化
索引是数据库中用于加速查询的一种数据结构。合理设计和优化索引可以显著提高查询性能。
1. 索引的类型
- B树索引:最常见的索引类型,适用于范围查询和精确查询。
- 哈希索引:适用于精确查询,但不支持范围查询。
- 全文索引:用于文本搜索,支持复杂的文本匹配。
2. 索引的创建策略
- 选择合适的列:为经常用于查询条件的列创建索引。
- 避免过多索引:过多的索引会增加插入、更新和删除操作的开销。
- 复合索引:为多个列创建复合索引,可以提高多列查询的性能。
3. 索引的维护
- 定期检查索引的使用情况:使用
EXPLAIN
或数据库的性能工具检查索引的使用情况。 - 重建索引:在索引碎片较多时,可以重建索引以提高性能。
- 删除无用的索引:删除那些从未被使用的索引,以减少维护开销。
4. 示例
假设我们有一个订单表orders
,包含以下字段:
order_id
:订单编号customer_id
:客户编号order_date
:订单日期
我们可以为customer_id
和order_date
创建复合索引:
CREATE INDEX idx_customer_order_date ON orders (customer_id, order_date);
这个索引将加速按客户编号和订单日期查询的性能。
三、性能优化
(一)查询执行计划分析
查询执行计划是数据库执行查询时的详细步骤。通过分析执行计划,可以了解查询的性能瓶颈。
1. 使用EXPLAIN
分析查询计划
EXPLAIN SELECT
customer_id,
SUM(order_amount) AS total_sales
FROM
orders
GROUP BY
customer_id;
EXPLAIN
将返回查询的执行计划,包括表的扫描方式、使用的索引、连接类型等信息。
2. 理解查询优化器的工作原理
查询优化器会根据表的统计信息和索引情况选择最优的执行计划。了解查询优化器的工作原理可以帮助我们更好地优化查询。
3. 示例
假设我们有一个订单表orders
,包含以下字段:
order_id
:订单编号customer_id
:客户编号order_amount
:订单金额
我们可以使用EXPLAIN
来分析查询计划:
EXPLAIN SELECT
customer_id,
SUM(order_amount) AS total_sales
FROM
orders
GROUP BY
customer_id;
通过分析执行计划,我们可以发现是否使用了索引,以及是否需要优化查询。
(二)性能调优
性能调优是提高SQL查询性能的关键步骤。以下是一些常见的性能调优技巧:
1. 索引优化策略
- 创建合适的索引:为经常用于查询条件的列创建索引。
- 避免过多索引:过多的索引会增加插入、更新和删除操作的开销。
- 使用复合索引:为多个列创建复合索引,可以提高多列查询的性能。
2. 查询重写技术
- 避免全表扫描:通过使用索引或优化查询条件,减少全表扫描。
- 减少子查询:将相关子查询转换为连接查询,减少子查询的执行次数。
- 使用派生表:将子查询的结果存储为派生表,减少重复计算。
3. 大数据量处理策略
- 分批处理:将大数据量的查询分成多个小批次处理,减少内存占用。
- 分区表:将表按逻辑分区,提高查询性能。
- 物化视图:使用物化视图存储复杂的查询结果,减少重复计算。
4. 示例
假设我们有一个订单表orders
,包含以下字段:
order_id
:订单编号customer_id
:客户编号order_amount
:订单金额
我们可以使用优化后的查询来查找每个客户的总销售额:
SELECT
customer_id,
SUM(order_amount) AS total_sales
FROM
orders
GROUP BY
customer_id;
通过创建索引CREATE INDEX idx_customer_id ON orders (customer_id);
,可以加速按customer_id
分组的查询性能。
四、数据库高级特性
(一)特定数据库技术
不同的数据库管理系统(如MySQL、PostgreSQL、Oracle)提供了各自独特的功能和技术。
1. MySQL
-
分区表:将表按逻辑分区,提高查询性能。
CREATE TABLE orders ( order_id INT, customer_id INT, order_amount DECIMAL(10, 2) ) PARTITION BY RANGE (customer_id) ( PARTITION p0 VALUES LESS THAN (1000), PARTITION p1 VALUES LESS THAN (2000), PARTITION p2 VALUES LESS THAN (3000) );
-
JSON支持:支持JSON数据类型,方便存储和查询JSON格式的数据。
CREATE TABLE users ( user_id INT, user_info JSON ); INSERT INTO users (user_id, user_info) VALUES (1, '{"name": "John", "age": 30}'); SELECT user_id, user_info->>'$.name' AS name, user_info->>'$.age' AS age FROM users;
2. PostgreSQL
-
分区表:支持表分区,提高查询性能。
CREATE TABLE orders ( order_id INT, customer_id INT, order_amount DECIMAL(10, 2) ) PARTITION BY RANGE (customer_id); CREATE TABLE orders_p0 PARTITION OF orders FOR VALUES FROM (1000) TO (2000); CREATE TABLE orders_p1 PARTITION OF orders FOR VALUES FROM (2000) TO (3000);
-
物化视图:支持物化视图,存储复杂的查询结果,减少重复计算。
CREATE MATERIALIZED VIEW customer_sales AS SELECT customer_id, SUM(order_amount) AS total_sales FROM orders GROUP BY customer_id;
3. Oracle
-
分区表:支持表分区,提高查询性能。
CREATE TABLE orders ( order_id INT, customer_id INT, order_amount DECIMAL(10, 2) ) PARTITION BY RANGE (customer_id) ( PARTITION p0 VALUES LESS THAN (1000), PARTITION p1 VALUES LESS THAN (2000), PARTITION p2 VALUES LESS THAN (3000) );
-
物化视图:支持物化视图,存储复杂的查询结果,减少重复计算。
CREATE MATERIALIZED VIEW customer_sales AS SELECT customer_id, SUM(order_amount) AS total_sales FROM orders GROUP BY customer_id;
(二)数据仓库与数据分析
数据仓库是一种用于存储和分析数据的数据库系统,主要用于支持决策支持系统(DSS)和商业智能(BI)。
1. 数据仓库的基本概念
- OLTP(在线事务处理):主要用于日常事务处理,强调数据的插入、更新和删除操作。
- OLAP(在线分析处理):主要用于数据分析,强调数据的查询和报表生成。
2. 数据分析中的高级SQL应用
-
数据透视表:使用SQL生成数据透视表,方便数据分析。
SELECT department_id, job_id, SUM(salary) AS total_salary FROM employees GROUP BY department_id, job_id;
-
时间序列分析:分析时间序列数据,如销售趋势。
SELECT order_date, SUM(order_amount) AS total_sales FROM orders GROUP BY order_date ORDER BY order_date;
3. 示例
假设我们有一个订单表orders
,包含以下字段:
order_id
:订单编号order_date
:订单日期order_amount
:订单金额
我们可以使用SQL生成销售趋势报表:
SELECT
order_date,
SUM(order_amount) AS total_sales
FROM
orders
GROUP BY
order_date
ORDER BY
order_date;
这个查询的结果将展示每天的销售总额,方便进行时间序列分析。
五、实践项目
(一)真实数据集分析
使用公开数据集(如电商数据、图书管理系统)进行复杂查询,是学习SQL高级应用的重要实践环节。
1. 电商数据集分析
假设我们有一个电商数据集,包含以下表:
orders
:订单表order_id
:订单编号customer_id
:客户编号order_date
:订单日期order_amount
:订单金额
customers
:客户表customer_id
:客户编号name
:客户姓名email
:客户邮箱
products
:产品表product_id
:产品编号product_name
:产品名称price
:产品价格
order_items
:订单详情表order_id
:订单编号product_id
:产品编号quantity
:购买数量
我们可以使用SQL进行以下复杂查询:
-
查询每个客户的总销售额:
SELECT c.customer_id, c.name, SUM(o.order_amount) AS total_sales FROM customers c JOIN orders o ON c.customer_id = o.customer_id GROUP BY c.customer_id, c.name ORDER BY total_sales DESC;
-
查询每个产品的销售数量:
SELECT p.product_id, p.product_name, SUM(oi.quantity) AS total_quantity FROM products p JOIN order_items oi ON p.product_id = oi.product_id GROUP BY p.product_id, p.product_name ORDER BY total_quantity DESC;
-
查询每个客户的订单明细:
SELECT c.customer_id, c.name, o.order_id, o.order_date, o.order_amount FROM customers c JOIN orders o ON c.customer_id = o.customer_id ORDER BY c.customer_id, o.order_date;
2. 图书管理系统数据集分析
假设我们有一个图书管理系统数据集,包含以下表:
books
:图书表book_id
:图书编号title
:图书标题author
:作者price
:价格
borrowers
:借阅者表borrower_id
:借阅者编号name
:借阅者姓名email
:借阅者邮箱
borrow_records
:借阅记录表record_id
:借阅记录编号borrower_id
:借阅者编号book_id
:图书编号borrow_date
:借阅日期return_date
:归还日期
我们可以使用SQL进行以下复杂查询:
-
查询每个借阅者的借阅记录:
SELECT b.borrower_id, b.name, br.record_id, br.borrow_date, br.return_date, bo.title AS book_title FROM borrowers b JOIN borrow_records br ON b.borrower_id = br.borrower_id JOIN books bo ON br.book_id = bo.book_id ORDER BY b.borrower_id, br.borrow_date;
-
查询每本图书的借阅次数:
SELECT bo.book_id, bo.title, COUNT(br.record_id) AS borrow_count FROM books bo JOIN borrow_records br ON bo.book_id = br.book_id GROUP BY bo.book_id, bo.title ORDER BY borrow_count DESC;
(二)复杂业务场景
解决实际业务中的复杂查询需求,是SQL高级应用的重要目标。以下是一些常见的复杂业务场景:
1. 多表连接
在实际业务中,经常需要连接多个表来获取完整的数据。例如,查询每个客户的订单明细和产品信息:
SELECT
c.customer_id,
c.name,
o.order_id,
o.order_date,
oi.product_id,
p.product_name,
oi.quantity,
oi.quantity * p.price AS total_price
FROM
customers c
JOIN
orders o ON c.customer_id = o.customer_id
JOIN
order_items oi ON o.order_id = oi.order_id
JOIN
products p ON oi.product_id = p.product_id
ORDER BY
c.customer_id, o.order_date;
2. 递归查询
递归查询在处理树状结构数据时非常有用。例如,查询员工的层级关系:
WITH RECURSIVE employee_hierarchy AS (
SELECT
employee_id,
manager_id,
1 AS level
FROM
employees
WHERE
manager_id IS NULL
UNION ALL
SELECT
e.employee_id,
e.manager_id,
eh.level + 1
FROM
employees e
JOIN
employee_hierarchy eh ON e.manager_id = eh.employee_id
)
SELECT
employee_id,
manager_id,
level
FROM
employee_hierarchy;
3. 时间序列分析
时间序列分析在数据分析中非常重要。例如,查询每月的销售总额:
SELECT
DATE_FORMAT(order_date, '%Y-%m') AS month,
SUM(order_amount) AS total_sales
FROM
orders
GROUP BY
month
ORDER BY
month;
(三)性能优化实践
性能优化是SQL高级应用的重要环节。以下是一些性能优化的实践案例:
1. 查询执行计划分析
通过分析查询执行计划,可以发现性能瓶颈。例如,使用EXPLAIN
分析查询计划:
EXPLAIN SELECT
customer_id,
SUM(order_amount) AS total_sales
FROM
orders
GROUP BY
customer_id;
通过分析执行计划,可以发现是否使用了索引,以及是否需要优化查询。
2. 索引优化
创建合适的索引可以显著提高查询性能。例如,为customer_id
创建索引:
CREATE INDEX idx_customer_id ON orders (customer_id);
通过创建索引,可以加速按customer_id
分组的查询性能。
3. 查询重写
将相关子查询转换为连接查询,可以减少子查询的执行次数。例如:
SELECT
e.employee_id,
e.salary,
d.avg_salary
FROM
employees e
JOIN
(SELECT
department_id,
AVG(salary) AS avg_salary
FROM
employees
GROUP BY
department_id) d
ON
e.department_id = d.department_id;
通过将相关子查询转换为连接查询,可以提高查询性能。
4. 大数据量处理
对于大数据量的查询,可以使用分批处理或分区表来提高性能。例如,将表按customer_id
分区:
CREATE TABLE orders (
order_id INT,
customer_id INT,
order_amount DECIMAL(10, 2)
) PARTITION BY RANGE (customer_id) (
PARTITION p0 VALUES LESS THAN (1000),
PARTITION p1 VALUES LESS THAN (2000),
PARTITION p2 VALUES LESS THAN (3000)
);
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 2025成都.NET开发者Connect圆满结束
· 后端思维之高并发处理方案
· 千万级大表的优化技巧
· 在 VS Code 中,一键安装 MCP Server!
· 10年+ .NET Coder 心语 ── 继承的思维:从思维模式到架构设计的深度解析