在不实际执行查询的情况下确定 Oracle 查询执行时间和建议的数据大小
Posted
技术标签:
【中文标题】在不实际执行查询的情况下确定 Oracle 查询执行时间和建议的数据大小【英文标题】:Determine Oracle query execution time and proposed datasize without actually executing query 【发布时间】:2015-04-29 10:02:07 【问题描述】:在 oracle 中是否有任何方法可以确定 sql 查询将花费多长时间来获取整个记录以及它的大小,而无需实际执行并等待整个结果。
我使用普通的 oracle SQL 选择(不是数据泵/导入等)反复下载并向用户提供数据。有时行数以百万计。
【问题讨论】:
如果您的统计数据是最新的,execution plan 将向您显示估计的行数。 但是如何获取查询将运行多长时间以及要检索的数据大小 执行计划不仅包括行数,还包括数据的大小。它还包括对运行时间的近似估计 - 但我从未见过它接近实际运行时间。 如果你有plsql然后将查询粘贴到sql窗口并按f5,它将显示你的执行计划,你可以看到查询的成本和其他有关记录的详细信息 @anudeepks "if you have plsql" 没有意义。 PL/SQL 是一种编程语言。您不能将任何内容“粘贴”到编程语言中 【参考方案1】:除非你运行它,否则不会知道实际运行时间,但你可以尝试估计它..
-
首先你可以explain plan只解释,这将不运行查询——根据你当前的统计数据,它会或多或少地告诉你它将如何执行
这将没有实际的时间和精力从数据块中读取数据..
你有大块吗
此架构是否针对查询/报告进行了规范化/反规范化?
在同一块中可以容纳多大的行,因此只需要 1 次提取?
您期望的行数
基于数据量 * 您的网络延迟基于此你可以尝试估计时间
【讨论】:
【参考方案2】:这需要很好的统计,explain plan for ...
,调整sys.aux_stats
,然后调整你的期望。
良好的统计数据 解释计划估计基于优化器统计数据。确保表和索引具有最新的统计信息。在 11g 上,这通常意味着坚持使用默认设置和任务,并且仅在大量数据加载后手动收集统计信息。
Explain plan for ...
使用这样的语句来创建和存储任何 SQL 语句的解释计划。这甚至适用于创建索引和表。
explain plan set statement_id = 'SOME_UNIQUE_STRING' for
select * from dba_tables cross join dba_tables;
这通常是可视化解释计划的最佳方式:
select * from table(dbms_xplan.display);
Plan hash value: 2788227900
-------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Time |
-------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 12M| 5452M| 00:00:19 |
|* 1 | HASH JOIN RIGHT OUTER | | 12M| 5452M| 00:00:19 |
| 2 | TABLE ACCESS FULL | SEG$ | 7116 | 319K| 00:00:01 |
...
原始数据存储在PLAN_TABLE
。计划的第一行通常总结了其他步骤的估计:
select cardinality, bytes, time
from plan_table
where statement_id = 'SOME_UNIQUE_STRING'
and id = 0;
CARDINALITY BYTES TIME
12934699 5717136958 19
调整 sys.aux_stats$ 时间估计基于存储在 sys.aux_stats
中的系统统计信息。这些是 CPU 速度、单块 I/O 读取时间等指标的数字。例如,在我的系统上:
select * from sys.aux_stats$ order by sname
SNAME PNAME PVAL1 PVAL2
SYSSTATS_INFO DSTART 09-11-2014 11:18
SYSSTATS_INFO DSTOP 09-11-2014 11:18
SYSSTATS_INFO FLAGS 1
SYSSTATS_INFO STATUS COMPLETED
SYSSTATS_MAIN CPUSPEED
SYSSTATS_MAIN CPUSPEEDNW 3201.10192837466
SYSSTATS_MAIN iosEEKTIM 10
SYSSTATS_MAIN IOTFRSPEED 4096
SYSSTATS_MAIN MAXTHR
SYSSTATS_MAIN MBRC
SYSSTATS_MAIN MREADTIM
SYSSTATS_MAIN SLAVETHR
SYSSTATS_MAIN SREADTIM
号码可以由dbms_stats.gather_system_stats
自动收集。它们也可以手动修改。这是一个 SYS 表,但修改起来相对安全。创建一些示例查询,将估计时间与实际时间进行比较,并调整数字直到它们匹配。
发现你可能浪费了很多时间
理论上,在所有情况下都无法正确预测运行时间,而在实践中,预测非平凡查询非常困难。乔纳森·刘易斯 (Jonathan Lewis) 写了一整篇关于这些预测的 book,而那本书只涵盖了“基础知识”。
如果估计值相差一到两个数量级,则复杂的解释计划通常“足够好”。但这种差异通常不足以向用户展示或用于做出任何重要决定。
【讨论】:
以上是关于在不实际执行查询的情况下确定 Oracle 查询执行时间和建议的数据大小的主要内容,如果未能解决你的问题,请参考以下文章
Django ORM:在不执行 N+1 查询的情况下检索帖子和最新评论
如何在不运行实际查询的情况下检查 JDBC 语句的 SQL 语法?