Oracle Execution Plan -- Statistics

本文探讨了针对SH模式的Oracle查询,关注执行计划中的关键指标,如使用的临时空间大小,该空间从PGA分配,涉及到优化器选择的内存分配策略。

Consider the follow query against SH schema.

select /*MY5*/ cust_id, sum(amount_sold) from sales where prod_id=:prod_id group by cust_id;
With DBMS_XPLAN.Display_cursor, user is able to retrieve and see execution plan.
SELECT t.*
FROM v$sql s, table(DBMS_XPLAN.DISPLAY_CURSOR(s.sql_id, s.child_number)) t WHERE sql_text LIKE '%/*MY5*/%';
Plan hash value: 2178334326


----------------------------------------------------------------------------------------------------------------------
| Id  | Operation                           | Name           | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |
----------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                    |                |       |       |   388 (100)|          |       |       |
|   1 |  HASH GROUP BY                      |                |  4051 | 56714 |   388   (1)| 00:00:05 |       |       |
|   2 |   PARTITION RANGE ALL               |                |  6002 | 84028 |   387   (0)| 00:00:05 |     1 |    28 |
|   3 |    TABLE ACCESS BY LOCAL INDEX ROWID| SALES          |  6002 | 84028 |   387   (0)| 00:00:05 |     1 |    28 |
|   4 |     BITMAP CONVERSION TO ROWIDS     |                |       |       |            |          |       |       |
|*  5 |      BITMAP INDEX SINGLE VALUE      | SALES_PROD_BIX |       |       |            |          |     1 |    28 |
----------------------------------------------------------------------------------------------------------------------


Predicate Information (identified by operation id):
---------------------------------------------------


   5 - access("PROD_ID"=:PROD_ID)
This reveals quite a bit of information, however, what if user would like to know how much memory allocation during the course of this query, how many rows Oracle visited, etc... DBMS_XPLAN.display_cursor provide a way to get these information.

More information from execution plan

alter session set statistics_level=ALL;            

Default value is 'TYPICAL'. In addition to statistics collected at 'TYPICAL' level, 'ALL' instructs Oracle to gather timed OS statistics and plan execution statistics.
SELECT t.*
FROM v$sql s, table(DBMS_XPLAN.DISPLAY_CURSOR(s.sql_id, s.child_number, 'TYPICAL ALLSTATS')) t WHERE sql_text LIKE '%/*MY5*/%';

ALLSTATS: 'IOSTATS MEMSTATS', shows both memory and IO statistics. In order for the memory statistics to be shown, the PGA management should be enabled. That is, PAG_AGGREGATE_TARGET=. The statistics are shown for all executions of the cursor.
To view the statistics of last execution, use 'TYPICAL ALLSTATS LAST'.

Interpreting statistics
SELECT t.*
FROM v$sql s, table(DBMS_XPLAN.DISPLAY_CURSOR(s.sql_id, s.child_number, 'TYPICAL ALLSTATS LAST')) t WHERE sql_text LIKE '%/*MY5*/%';
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                           | Name           | Starts | E-Rows |E-Bytes| Cost (%CPU)| E-Time   | Pstart| Pstop | A-Rows |   A-Time   | Buffers |  OMem |  1Mem | Used-Mem |
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                    |                |      1 |        |       |   388 (100)|          |       |       |   2492 |00:00:00.26 |     100 |       |       |          |
|   1 |  HASH GROUP BY                      |                |      1 |   4051 | 56714 |   388   (1)| 00:00:05 |       |       |   2492 |00:00:00.26 |     100 |   934K|   934K| 1356K (0)|
|   2 |   PARTITION RANGE ALL               |                |      1 |   6002 | 84028 |   387   (0)| 00:00:05 |     1 |    28 |   6002 |00:00:00.20 |     100 |       |       |          |
|   3 |    TABLE ACCESS BY LOCAL INDEX ROWID| SALES          |     28 |   6002 | 84028 |   387   (0)| 00:00:05 |     1 |    28 |   6002 |00:00:00.12 |     100 |       |       |          |
|   4 |     BITMAP CONVERSION TO ROWIDS     |                |     28 |        |       |            |          |       |       |   6002 |00:00:00.02 |      44 |       |       |          |
|*  5 |      BITMAP INDEX SINGLE VALUE      | SALES_PROD_BIX |     28 |        |       |            |          |     1 |    28 |     16 |00:00:00.01 |      44 |       |       |          |
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Starts: 
E-Rows: Estimated Number of Rows. "Rows" column from the output of "explain plan" command.
E-Bytes: Estimated Bytes
E-Time: Estimated Time
A-Rows: Actual Rows
A-Time: Actual Time
Buffers: Logical Reads. consistent gets + current gets
Reads: Physical Reads. Only show up when it has a non-zero value.
Writes: Number of writes to temp space.
0Mem: Estimated_Optimal_Size of v$sql_workarea. Esimated size in KB to perform the operation totally in memory (optimal execution). This is the ideal size.
1Mem: Esimated_OnePass_size of v$sql_workarea. Estimated size in KB to execute the operation in one pass. With one pass size, the response time is increased.
Used-Mem: Last_Memory_Used of v$sql_workarea. Memory used during the last execution of the cursor.

Used-Temp: Size of temp space used. Both optimal size and one-pass size memory are allocated from PGA.



在数据库查询执行过程中,出现“Cannot generate a valid execution plan for the given query”错误通常表明查询优化器无法为当前的SQL语句生成有效的执行计划。这种情况可能由多种原因导致,包括但不限于表结构设计不合理、索引缺失或失效、统计信息不准确、查询条件过于复杂或存在歧义等。 ### 查询优化策略与执行计划生成机制 数据库优化器(如CBO,基于成本的优化器)会尝试探索不同的执行路径,并选择成本最低的方案来执行查询。在某些情况下,如果使用了特定的优化模式(如fast-response方法),优化器可能会优先考虑快速返回前n行数据的执行计划,而不是整体最优的执行计划[^1]。这种策略可能导致某些复杂的查询无法生成完整的执行计划,尤其是在需要获取全部结果集的情况下。 因此,在编写查询时,应避免使用可能导致优化器难以判断的复杂逻辑,例如过多的子查询嵌套、复杂的OR条件组合等。可以将部分逻辑转换为显式的JOIN操作,以提高可读性和优化器识别效率。 ```sql -- 示例:优化前 SELECT * FROM orders WHERE customer_id IN (SELECT id FROM customers WHERE region = 'Asia'); -- 优化后 SELECT o.* FROM orders o JOIN customers c ON o.customer_id = c.id WHERE c.region = 'Asia'; ``` ### 索引与统计信息的作用 如果查询中涉及的列(尤其是WHERE、JOIN和ORDER BY子句中的列)没有适当的索引支持,优化器将难以生成高效的执行计划。可以通过以下方式检查并添加索引: ```sql -- 查看现有索引 SHOW INDEX FROM your_table; -- 添加索引示例 ALTER TABLE your_table ADD INDEX idx_name (column_name); ``` 对于大型表,建议对频繁查询的字段组合建立复合索引,同时避免过度索引造成写入性能下降。此外,数据库优化器依赖统计信息来估算行数和选择最优路径。若统计信息过时,可能导致执行计划不佳甚至失败。可以手动更新统计信息以帮助优化器做出更准确的决策: ```sql -- MySQL ANALYZE TABLE your_table; -- PostgreSQL VACUUM ANALYZE your_table; -- SQL Server UPDATE STATISTICS your_table; ``` ### 参数设置与资源限制的影响 某些数据库系统(如PostgreSQL、MySQL)允许配置查询优化器的行为。例如: - `statement_timeout`(PostgreSQL) - `max_execution_time`(MySQL) 如果这些参数设置过短,可能导致优化器提前放弃生成计划。此外,内存不足也可能影响执行计划生成。应适当调整相关参数并监控系统资源使用情况。 ### 使用提示(Hints)引导优化器 在某些情况下,可以通过使用查询提示(hints)引导优化器选择特定的执行路径。例如,在Oracle中可以使用`/*+ FULL(table) */`提示强制全表扫描: ```sql SELECT /*+ FULL(employees) */ * FROM employees WHERE department_id = 10; ``` 在SQL Server中也可以使用类似语法控制JOIN顺序或索引使用。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值