1. 理解ORDER BY的基础功能
在Oracle数据库中,ORDER BY子句是SQL查询中最常用的排序工具。它的核心作用是对查询结果集按照一个或多个列进行升序或降序排列。作为数据展示前的最后一道工序,ORDER BY直接决定了最终呈现给用户的数据顺序。
ORDER BY的基本语法结构非常简单:
sql复制SELECT column1, column2, ...
FROM table_name
ORDER BY column1 [ASC|DESC], column2 [ASC|DESC], ...;
这里有几个关键点需要注意:
- ASC表示升序(默认),DESC表示降序
- 可以指定多个排序列,优先级按书写顺序
- 排序列可以是SELECT列表中的列,也可以是表中其他列
- 支持使用列位置编号代替列名(但不推荐)
实际开发中建议始终显式指定ASC或DESC,即使使用默认升序。这能提高代码可读性并避免团队协作时的理解偏差。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. ORDER BY的高级用法解析
2.1 多列排序与排序优先级
当需要按多个字段排序时,ORDER BY子句中的列顺序决定了排序优先级。例如人力资源系统中常见的员工排序需求:
sql复制SELECT employee_id, last_name, department_id, salary
FROM employees
ORDER BY department_id ASC, salary DESC;
这个查询会先按部门ID升序排列,在相同部门内再按薪资降序排列。多列排序是报表类应用中最常用的功能之一。
2.2 使用表达式排序
ORDER BY不仅支持列名,还支持各种表达式排序。这在业务逻辑复杂的场景中非常实用:
sql复制-- 按计算字段排序
SELECT product_name, unit_price, units_in_stock,
unit_price * units_in_stock AS inventory_value
FROM products
ORDER BY inventory_value DESC;
-- 使用函数排序
SELECT order_id, customer_id, order_date
FROM orders
ORDER BY TO_CHAR(order_date, 'YYYY-MM');
2.3 NULL值的排序处理
NULL值在排序中的处理需要特别注意。Oracle默认将NULL值视为最大值,即:
- ASC排序时NULL出现在最后
- DESC排序时NULL出现在最前
可以使用NULLS FIRST/NULLS LAST显式控制:
sql复制-- 让NULL值优先显示
SELECT employee_id, commission_pct
FROM employees
ORDER BY commission_pct ASC NULLS FIRST;
-- 让NULL值最后显示(默认ASC行为)
SELECT employee_id, commission_pct
FROM employees
ORDER BY commission_pct ASC NULLS LAST;
3. ORDER BY性能优化技巧
3.1 索引与ORDER BY
合理的索引设计可以显著提升排序性能。当ORDER BY子句中的列有索引时,Oracle可能避免实际排序操作:
sql复制-- 为常用排序字段创建索引
CREATE INDEX idx_emp_dept_salary ON employees(department_id, salary);
-- 复合索引的列顺序应与ORDER BY一致
SELECT employee_id, last_name
FROM employees
ORDER BY department_id, salary; -- 能使用上述索引
注意:包含函数或表达式的ORDER BY通常无法使用索引,如ORDER BY UPPER(last_name)
3.2 大数据量排序优化
当处理百万级数据排序时,可以考虑以下方案:
- 增加PGA内存:
sql复制ALTER SYSTEM SET pga_aggregate_target=2G;
- 使用/*+ FIRST_ROWS */提示优先返回部分结果:
sql复制SELECT /*+ FIRST_ROWS(100) */ *
FROM large_table
ORDER BY create_date DESC;
- 分页查询时确保使用ROWNUM过滤后再排序:
sql复制-- 错误做法(先排序全表再取前N条)
SELECT *
FROM (SELECT * FROM large_table ORDER BY create_date DESC)
WHERE ROWNUM <= 100;
-- 正确做法(12c以下版本)
SELECT *
FROM (SELECT a.*, ROWNUM rnum
FROM (SELECT * FROM large_table ORDER BY create_date DESC) a
WHERE ROWNUM <= 100)
WHERE rnum >= 1;
-- 12c及以上版本使用OFFSET-FETCH
SELECT * FROM large_table
ORDER BY create_date DESC
OFFSET 0 ROWS FETCH NEXT 100 ROWS ONLY;
4. 特殊场景下的ORDER BY应用
4.1 中文拼音排序
处理中文数据时,经常需要按拼音排序:
sql复制-- 使用NLSSORT函数
SELECT employee_name
FROM employees
ORDER BY NLSSORT(employee_name, 'NLS_SORT=SCHINESE_PINYIN_M');
4.2 自定义排序规则
对于有特殊排序需求的业务场景(如状态字段按业务规则排序):
sql复制-- 使用DECODE或CASE实现自定义排序
SELECT order_id, status
FROM orders
ORDER BY DECODE(status,
'Pending', 1,
'Processing', 2,
'Shipped', 3,
'Completed', 4,
5); -- 其他状态
4.3 分组排序(窗口函数)
Oracle的窗口函数可以实现高级分组排序:
sql复制-- 每个部门内按薪资排序
SELECT department_id, last_name, salary,
RANK() OVER (PARTITION BY department_id ORDER BY salary DESC) AS dept_rank
FROM employees;
5. 常见问题与解决方案
5.1 ORA-00904: 无效标识符
sql复制-- 错误:排序列不在SELECT列表中且表别名使用不当
SELECT e.employee_id
FROM employees e
ORDER BY department_id; -- 应该用e.department_id
-- 正确写法
SELECT e.employee_id
FROM employees e
ORDER BY e.department_id;
5.2 排序结果不符合预期
可能原因:
- 字符集排序规则不一致
- 数据类型隐式转换
- NULL值处理不符合预期
解决方案:
sql复制-- 明确指定排序规则
SELECT product_name
FROM products
ORDER BY NLSSORT(product_name, 'NLS_SORT=BINARY_CI');
-- 显式转换数据类型
SELECT order_id, order_date
FROM orders
ORDER BY TO_DATE(order_date, 'YYYY-MM-DD');
5.3 分页排序性能问题
典型错误模式:
sql复制-- 低效写法(12c以下版本)
SELECT *
FROM (SELECT a.*, ROWNUM rnum
FROM (SELECT * FROM large_table) a
WHERE ROWNUM <= 20)
WHERE rnum >= 10
ORDER BY create_date; -- 排序在分页后执行!
正确做法:
sql复制-- 排序必须在最内层完成
SELECT *
FROM (SELECT a.*, ROWNUM rnum
FROM (SELECT * FROM large_table ORDER BY create_date) a
WHERE ROWNUM <= 20)
WHERE rnum >= 10;
6. 实际案例:电商平台订单排序
假设我们需要为电商后台实现一个灵活的订单排序功能:
sql复制-- 基础排序:按日期降序
SELECT order_id, customer_id, order_date, total_amount, status
FROM orders
ORDER BY order_date DESC;
-- 多条件排序:先状态再金额
SELECT order_id, customer_id, order_date, total_amount, status
FROM orders
ORDER BY
DECODE(status, 'Pending',1, 'Paid',2, 'Shipped',3, 'Completed',4,5),
total_amount DESC;
-- 带搜索条件的排序
SELECT order_id, customer_id, order_date, total_amount
FROM orders
WHERE order_date >= TRUNC(SYSDATE) - 30
AND customer_id LIKE 'CUST%'
ORDER BY
CASE WHEN total_amount > 1000 THEN 0 ELSE 1 END, -- 大额订单优先
order_date DESC;
对于这类应用,建议在应用层实现动态排序构建,例如:
java复制// Java示例:动态构建ORDER BY
StringBuilder orderBy = new StringBuilder("ORDER BY ");
if (sortBy.equals("date")) {
orderBy.append("order_date ").append(ascending ? "ASC" : "DESC");
} else if (sortBy.equals("amount")) {
orderBy.append("total_amount ").append(ascending ? "ASC" : "DESC");
}
// 添加到SQL查询
7. ORDER BY与其他子句的执行顺序
理解SQL各子句的执行顺序对编写正确查询至关重要:
- FROM:确定数据源
- WHERE:过滤行
- GROUP BY:分组
- HAVING:过滤分组
- SELECT:选择列
- ORDER BY:排序结果
这意味着:
- ORDER BY可以使用SELECT中定义的别名
- WHERE中不能使用SELECT中的别名
- 聚合函数只能在HAVING或ORDER BY中使用
sql复制-- 正确:ORDER BY使用SELECT别名
SELECT department_id, AVG(salary) AS avg_sal
FROM employees
GROUP BY department_id
ORDER BY avg_sal DESC;
-- 错误:WHERE不能使用SELECT别名
SELECT employee_id, salary, salary*12 AS annual_sal
FROM employees
WHERE annual_sal > 100000; -- 错误!
8. 排序相关的Oracle参数配置
以下几个Oracle参数会影响排序性能:
SORT_AREA_SIZE:每个会话的排序内存大小PGA_AGGREGATE_TARGET:PGA内存总目标_SMM_MAX_SIZE:单个排序操作最大内存_SMM_PX_MAX_SIZE:并行排序最大内存
查看当前排序参数:
sql复制SELECT name, value, display_value
FROM v$parameter
WHERE name LIKE '%sort%' OR name LIKE '%pga%';
调整排序内存(需DBA权限):
sql复制ALTER SYSTEM SET pga_aggregate_target=4G SCOPE=BOTH;
监控排序操作:
sql复制SELECT sid, username, sql_id, blocks, temp_blks
FROM v$sort_usage;
9. 排序算法内部原理
Oracle使用多种排序算法,主要包括:
-
内存排序(最优情况)
- 使用快速排序等算法
- 完全在PGA中完成
-
磁盘排序(当数据超过内存)
- 使用归并排序算法
- 需要临时表空间存储中间结果
- 显著影响性能
通过执行计划识别排序操作:
sql复制EXPLAIN PLAN FOR
SELECT * FROM employees ORDER BY hire_date;
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);
输出中的SORT ORDER BY操作表示发生了排序。如果看到SORT GROUP BY、SORT JOIN等也表示需要排序操作。
减少排序操作的方法:
- 使用索引避免排序
- 减少SELECT列数
- 使用UNION ALL代替UNION(UNION需要去重排序)
- 避免不必要的DISTINCT
10. 排序在分析函数中的应用
分析函数中的ORDER BY与SQL级的ORDER BY有不同作用:
sql复制-- SQL级ORDER BY(最终结果排序)
SELECT department_id, last_name, salary
FROM employees
ORDER BY department_id, salary DESC;
-- 分析函数中的ORDER BY(确定窗口框架)
SELECT department_id, last_name, salary,
AVG(salary) OVER (PARTITION BY department_id ORDER BY hire_date
ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING) AS moving_avg
FROM employees;
典型分析函数排序场景:
- RANK()/DENSE_RANK():确定排名顺序
- ROW_NUMBER():生成行号
- LAG()/LEAD():访问相邻行
- FIRST_VALUE()/LAST_VALUE():获取窗口边界值
11. 排序与分页的完美结合
现代分页查询的最佳实践:
Oracle 12c之前:
sql复制SELECT *
FROM (SELECT a.*, ROWNUM rnum
FROM (SELECT * FROM large_table
ORDER BY create_date DESC) a
WHERE ROWNUM <= :page_end)
WHERE rnum >= :page_start;
Oracle 12c引入的ANSI标准语法:
sql复制SELECT * FROM large_table
ORDER BY create_date DESC
OFFSET :page_start ROWS FETCH NEXT :page_size ROWS ONLY;
性能考虑:
- 确保ORDER BY使用索引
- 避免深层分页(OFFSET过大)
- 考虑使用"上一页/下一页"代替随机跳页
12. 排序在报表中的应用技巧
报表开发中常用的排序模式:
- 分组小计报表:
sql复制SELECT department_id,
job_id,
COUNT(*) AS emp_count,
SUM(salary) AS total_sal
FROM employees
GROUP BY department_id, job_id
ORDER BY department_id, total_sal DESC;
- 交叉表报表:
sql复制SELECT *
FROM (SELECT department_id,
TO_CHAR(hire_date, 'YYYY') AS hire_year,
salary
FROM employees)
PIVOT (AVG(salary) FOR hire_year IN ('2020' AS "2020", '2021' AS "2021"))
ORDER BY department_id;
- 排名报表:
sql复制SELECT department_id, last_name, salary,
RANK() OVER (PARTITION BY department_id ORDER BY salary DESC) AS dept_rank
FROM employees
ORDER BY department_id, dept_rank;
13. 排序与物化视图
物化视图可以预排序数据以提高查询性能:
sql复制CREATE MATERIALIZED VIEW mv_emp_sorted
REFRESH COMPLETE ON DEMAND
ENABLE QUERY REWRITE
AS
SELECT * FROM employees
ORDER BY department_id, salary DESC;
使用提示强制查询重写:
sql复制SELECT /*+ REWRITE(mv_emp_sorted) */ employee_id, last_name
FROM employees
ORDER BY department_id, salary DESC;
物化视图排序的优点:
- 数据已预先排序,查询时无需计算
- 特别适合频繁访问的固定排序模式
- 可以结合分区提高性能
14. 排序在数据迁移中的应用
数据导出时合理排序可以提高导入性能:
sql复制-- 导出时按主键排序
EXPDP scott/tiger TABLES=employees QUERY=\"ORDER BY employee_id\"
-- 导入时按排序顺序加载
IMPDP scott/tiger TABLE_EXISTS_ACTION=append
对于跨数据库迁移,排序可以确保一致性:
sql复制-- 从Oracle迁移到MySQL
SELECT * FROM employees
ORDER BY department_id, employee_id
INTO OUTFILE '/tmp/employees.csv'
FIELDS TERMINATED BY ','
LINES TERMINATED BY '\n';
15. 排序与并行查询
利用并行处理加速大表排序:
sql复制ALTER SESSION ENABLE PARALLEL DML;
SELECT /*+ PARALLEL(employees 4) */ *
FROM employees
ORDER BY salary DESC;
监控并行排序:
sql复制SELECT sid, qcsid, server_group, server_set, server#
FROM v$px_session
WHERE qcsid = SYS_CONTEXT('USERENV','SID');
并行排序的注意事项:
- 需要足够CPU资源
- 可能增加PGA内存使用
- 不适合小表
- 可能引起临时表空间争用
16. 排序与分区表的结合
分区表可以显著提升排序性能:
sql复制-- 按范围分区的表
CREATE TABLE sales (
sale_id NUMBER,
sale_date DATE,
amount NUMBER
)
PARTITION BY RANGE (sale_date) (
PARTITION sales_q1 VALUES LESS THAN (TO_DATE('2023-04-01','YYYY-MM-DD')),
PARTITION sales_q2 VALUES LESS THAN (TO_DATE('2023-07-01','YYYY-MM-DD')),
PARTITION sales_q3 VALUES LESS THAN (TO_DATE('2023-10-01','YYYY-MM-DD')),
PARTITION sales_q4 VALUES LESS THAN (TO_DATE('2024-01-01','YYYY-MM-DD'))
);
-- 分区消除+排序
SELECT * FROM sales
WHERE sale_date BETWEEN TO_DATE('2023-06-01','YYYY-MM-DD')
AND TO_DATE('2023-08-31','YYYY-MM-DD')
ORDER BY sale_date;
分区表排序的优势:
- 只需要排序相关分区数据
- 可以并行处理不同分区
- 减少临时表空间使用
17. 排序与内存优化
优化排序内存使用的技巧:
- 减少排序列数量:
sql复制-- 不好:选择所有列
SELECT * FROM employees ORDER BY last_name;
-- 更好:只选择需要的列
SELECT employee_id, last_name FROM employees ORDER BY last_name;
- 使用压缩技术:
sql复制ALTER TABLE employees COMPRESS FOR OLTP;
- 调整排序区大小:
sql复制-- 会话级调整
ALTER SESSION SET sort_area_size = 10485760; -- 10MB
- 使用NOSORT选项创建索引(当数据已经有序时):
sql复制CREATE INDEX idx_emp_id ON employees(employee_id) NOSORT;
18. 排序与临时表空间
排序操作使用临时表空间的情况:
- 监控临时表空间使用:
sql复制SELECT tablespace_name, bytes_used, bytes_free
FROM v$temp_space_header;
- 创建专用的临时表空间:
sql复制CREATE TEMPORARY TABLESPACE temp_sort
TEMPFILE '/u01/oradata/temp_sort01.dbf' SIZE 2G
AUTOEXTEND ON NEXT 512M MAXSIZE 10G
EXTENT MANAGEMENT LOCAL UNIFORM SIZE 16M;
- 为用户分配专用临时表空间:
sql复制ALTER USER scott TEMPORARY TABLESPACE temp_sort;
- 临时表空间最佳实践:
- 与系统临时表空间分离
- 根据排序数据量合理设置大小
- 使用多个临时文件分散I/O
- 定期监控使用情况
19. 排序与统计信息
准确的统计信息对优化器选择排序策略至关重要:
- 收集表统计信息:
sql复制EXEC DBMS_STATS.GATHER_TABLE_STATS('SCOTT', 'EMPLOYEES');
- 收集列统计信息:
sql复制EXEC DBMS_STATS.GATHER_TABLE_STATS(
ownname => 'SCOTT',
tabname => 'EMPLOYEES',
method_opt => 'FOR COLUMNS SIZE 254 department_id');
- 收集系统统计信息:
sql复制EXEC DBMS_STATS.GATHER_SYSTEM_STATS();
- 锁定重要统计信息:
sql复制EXEC DBMS_STATS.LOCK_TABLE_STATS('SCOTT', 'EMPLOYEES');
统计信息影响排序的场景:
- 优化器决定使用索引还是全表扫描
- 决定是否使用并行处理
- 内存排序与磁盘排序的选择
- 连接操作的排序策略
20. 排序与执行计划控制
使用提示控制排序行为:
- 强制使用索引排序:
sql复制SELECT /*+ INDEX(employees emp_dept_idx) */ *
FROM employees
ORDER BY department_id;
- 禁止排序操作:
sql复制SELECT /*+ NO_ORDER_SUBQ */ employee_id
FROM employees e
WHERE department_id = (
SELECT /*+ NO_ORDER_SUBQ */ department_id
FROM departments
WHERE department_name = 'IT'
);
- 控制排序算法:
sql复制SELECT /*+ SORT_AREA_SIZE(104857600) */ *
FROM large_table
ORDER BY create_date;
- 使用CARDINALITY提示影响排序策略:
sql复制SELECT /*+ CARDINALITY(employees 10000) */ *
FROM employees
ORDER BY salary;
理解执行计划中的排序操作:
- SORT ORDER BY:显式排序
- SORT GROUP BY:分组排序
- SORT JOIN:连接排序
- SORT AGGREGATE:聚合排序
- SORT UNIQUE:去重排序
21. 排序与函数索引
函数索引可以支持特殊排序需求:
- 创建函数索引:
sql复制CREATE INDEX emp_upper_name_idx ON employees(UPPER(last_name));
- 使用函数索引排序:
sql复制SELECT * FROM employees
ORDER BY UPPER(last_name); -- 能使用上述索引
- 基于表达式的函数索引:
sql复制CREATE INDEX emp_annual_sal_idx ON employees(salary*12);
- 使用虚拟列+索引:
sql复制ALTER TABLE employees ADD annual_salary AS (salary*12);
CREATE INDEX emp_annual_sal_idx ON employees(annual_salary);
函数索引的注意事项:
- 增加DML操作开销
- 需要更多存储空间
- 不是所有函数都支持
- 可能需要设置特定参数
22. 排序与物化视图日志
物化视图日志可以记录排序变化:
sql复制-- 创建支持快速刷新的物化视图
CREATE MATERIALIZED VIEW LOG ON employees
WITH SEQUENCE, ROWID (employee_id, last_name, salary)
INCLUDING NEW VALUES;
CREATE MATERIALIZED VIEW mv_emp_sorted
REFRESH FAST ON COMMIT
AS
SELECT employee_id, last_name, salary
FROM employees
ORDER BY salary DESC;
这种方案适合:
- 基础表频繁更新但排序需求固定
- 需要实时或近实时排序数据
- 查询性能要求高于维护成本
23. 排序与结果缓存
利用服务器端结果缓存避免重复排序:
sql复制-- 使用结果缓存提示
SELECT /*+ RESULT_CACHE */ *
FROM employees
ORDER BY hire_date DESC;
监控结果缓存:
sql复制SELECT name, status, block_count, column_count, scan_count
FROM v$result_cache_objects;
结果缓存适合:
- 排序逻辑复杂但数据变化不频繁
- 相同排序查询被频繁执行
- 排序结果集不大
24. 排序与内存表
Oracle 18c引入的内存表特性可以加速排序:
sql复制-- 创建内存表
CREATE TABLE mem_employees (
employee_id NUMBER,
last_name VARCHAR2(100),
salary NUMBER
) INMEMORY;
-- 插入数据后,排序操作主要在内存完成
SELECT * FROM mem_employees
ORDER BY salary DESC;
内存表排序的优势:
- 避免磁盘I/O
- 使用优化的内存格式
- 支持列式处理
- 自动压缩
25. 排序与JSON数据
Oracle 12c开始支持JSON数据的排序:
sql复制-- 创建包含JSON列的表
CREATE TABLE products (
id NUMBER,
product_data CLOB CHECK (product_data IS JSON)
);
-- 按JSON属性排序
SELECT id, JSON_VALUE(product_data, '$.name') AS product_name
FROM products
ORDER BY JSON_VALUE(product_data, '$.price' RETURNING NUMBER);
JSON排序的注意事项:
- 使用JSON_VALUE提取排序键
- 明确指定返回数据类型
- 考虑创建函数索引
- 可能性能不如结构化数据
26. 排序与空间数据
Oracle Spatial数据的排序处理:
sql复制-- 按距离排序
SELECT s.store_id, s.store_name,
SDO_GEOM.SDO_DISTANCE(
s.location,
SDO_GEOMETRY(2001, 4326,
SDO_POINT_TYPE(-73.9855, 40.7484, NULL), NULL, NULL),
0.005, 'unit=km') AS distance_km
FROM stores s
ORDER BY distance_km;
空间排序的特殊考虑:
- 需要空间索引支持
- 距离计算开销大
- 考虑使用近似计算
- 可能需要分区处理
27. 排序与全文检索
结合全文索引的排序:
sql复制-- 创建全文索引
CREATE INDEX docs_text_idx ON documents(text)
INDEXTYPE IS CTXSYS.CONTEXT;
-- 按相关性排序
SELECT doc_id, title,
SCORE(1) AS relevance
FROM documents
WHERE CONTAINS(text, 'Oracle ORDER BY', 1) > 0
ORDER BY relevance DESC;
全文检索排序的特点:
- 基于相关性评分
- 可以结合其他排序条件
- 需要维护索引
- 支持高级语言特性
28. 排序与机器学习
在Oracle机器学习中的排序应用:
sql复制-- 使用PREDICTION函数排序
SELECT customer_id,
PREDICTION(customer_cluster_model USING *) AS cluster_id
FROM customers
ORDER BY PREDICTION_PROBABILITY(customer_cluster_model, 1 USING *) DESC;
机器学习排序的优势:
- 基于模型预测而非简单规则
- 可以处理复杂模式
- 实时适应数据变化
- 结合多种因素
29. 排序与区块链表
Oracle 21c区块链表的排序特性:
sql复制-- 创建区块链表
CREATE BLOCKCHAIN TABLE ledger_entries (
entry_id NUMBER,
entry_date TIMESTAMP,
amount NUMBER
) NO DROP UNTIL 30 DAYS IDLE
NO DELETE LOCKED
HASHING USING "SHA2_512" VERSION "v1";
-- 查询时排序仍可用
SELECT * FROM ledger_entries
ORDER BY entry_date DESC;
区块链表排序的限制:
- 数据不可修改影响某些排序场景
- 需要额外哈希计算
- 保留策略影响长期排序
30. 排序最佳实践总结
经过以上各种场景的分析,总结Oracle ORDER BY最佳实践:
-
索引策略:
- 为常用排序字段创建合适索引
- 考虑复合索引的列顺序
- 对函数排序使用函数索引
-
性能优化:
- 避免大结果集排序
- 使用分页技术减少排序量
- 合理配置PGA和临时表空间
-
SQL编写:
- 明确指定ASC/DESC
- 处理NULL值的显示顺序
- 减少排序列数量
- 考虑使用分析函数替代
-
架构设计:
- 对固定排序模式考虑物化视图
- 大数据量考虑分区策略
- 频繁排序考虑内存表
-
监控维护:
- 监控临时表空间使用
- 定期收集统计信息
- 检查执行计划中的排序操作
实际项目中,我曾遇到一个性能问题:一个报表查询需要对500万条记录按3个字段排序,最初需要25秒完成。通过以下优化步骤降到3秒内:
- 创建复合索引匹配排序字段顺序
- 增加PGA内存大小
- 使用并行查询提示
- 将临时表空间迁移到高速存储
这个案例说明,排序优化需要综合考虑数据库配置、SQL编写和物理设计多个方面。
