sql - Oracle 中的性能问题(公用表表达式和全局临时表之间的差异)
问题描述
我的一个查询存在性能问题。
查询的结构如下
With a02 as
(...
);
SELECT *
FROM
a02
inner join
a03 on a02.id=a03.id;
表 a02 大约 10000 行,表 a03 大约 40000 行。查询运行大约需要1.5 小时。
但是,如果我将 a02 创建为全局临时表,然后运行下面的查询,则需要不到5 mins。这是正常行为吗?
SELECT *
FROM
a02
inner join
a03 on a02.id=a03.id
我对使用全局临时表犹豫不决,因为我们有时会在删除表时收到以下消息:
删除表 A02;
SQL 错误:ORA-14452:尝试在已使用的临时表上创建、更改或删除索引 14452。00000 -“尝试在已使用的临时表上创建、更改或删除索引”
解决方案
我建议确定查询的 SQL id,然后使用 SQL Monitor Report,因为它会准确地告诉您执行计划是什么以及 SQL 花费大部分时间的位置。
从 SQL*Plus 获取 SQL Monitor Report 的简单方法如下:
spool c:\temp\SQL_Monitor_rpt.html
SET LONG 1000000
SET LONGCHUNKSIZE 1000000
SET LINESIZE 1000
SET PAGESIZE 0
SET TRIM ON
SET TRIMSPOOL ON
SET ECHO OFF
SET FEEDBACK OFF
alter session set "_with_subquery" = optimizer;
SELECT DBMS_SQLTUNE.report_sql_monitor(
sql_id => '&SQLID' ,
type => 'HTML',
report_level => 'ALL') AS report
FROM dual;
spool off
很可能在不使用索引的情况下进行全表扫描和连接。您可能应该索引连接条件中涉及的两个表中的列。此外,您可以尝试在 WITH 子句子查询中使用 /*+ MATERIALIZE */ 提示来模拟全局临时表,而实际上不需要它。
推荐阅读
- node.js - 创建新用户 Knex Postgresql Node.js 时出现数据类型错误
- postgresql - pgAdmin 致命错误 - sqlalchemy.exc.OperationalError
- html - 第三级导航菜单不隐藏
- flutter - Flutter嵌套页面提供程序模型不刷新
- flask - flask_socketio 客户端没有收到在另一个使用多进程的请求中处理的数据
- python - 如何将使用 Matplotlib 的 bar_label 创建的标签格式化为四舍五入的百分比?
- html - 如何使用 css 在 3d 空间中旋转 svg
- java - 在Java中将字符串键值映射转换为枚举键值
- python - libusb 找不到连接到计算机的特定设备
- sql - 访问,多个iif功能合二为一