Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oracle 为什么优化器计划与实验查询运行不相关?_Oracle_Database Performance_Oracle12c_Sqlperformance_Cost Based Optimizer - Fatal编程技术网

Oracle 为什么优化器计划与实验查询运行不相关?

Oracle 为什么优化器计划与实验查询运行不相关?,oracle,database-performance,oracle12c,sqlperformance,cost-based-optimizer,Oracle,Database Performance,Oracle12c,Sqlperformance,Cost Based Optimizer,假设我们有以下问题: 给定一个具有一列“X”的表,其中包含一些带有随机变量的行 从1到100的整数: CREATE TABLE xtable(x) AS SELECT ceil(dbms_random.value * 100) FROM dual CONNECT BY level <= 1000000; 二, 三, 计划是在Oracle 12.1.0.2.0上获得的无法复制第二个计划。下面是: ----------------------------------

假设我们有以下问题:

给定一个具有一列“X”的表,其中包含一些带有随机变量的行 从1到100的整数:

CREATE TABLE xtable(x) AS 
   SELECT ceil(dbms_random.value * 100) 
     FROM dual
   CONNECT BY level <= 1000000;
二,

三,


计划是在Oracle 12.1.0.2.0上获得的

无法复制第二个计划。下面是:

-------------------------------------------------------------------------------------------                                       
| Id  | Operation              | Name     | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     |                                       
-------------------------------------------------------------------------------------------                                       
|   0 | DELETE STATEMENT       |          |       |       |       |  3648 (100)|          |                                       
|   1 |  DELETE                | XTABLE   |       |       |       |            |          |                                       
|   2 |   MERGE JOIN ANTI NA   |          |   999K|    26M|       |  3648   (5)| 00:00:01 |                                       
|   3 |    SORT JOIN           |          |  1000K|  2929K|    22M|  3147   (3)| 00:00:01 |                                       
|   4 |     TABLE ACCESS FULL  | XTABLE   |  1000K|  2929K|       |   434   (3)| 00:00:01 |                                       
|*  5 |    SORT UNIQUE         |          |   100 |  2500 |       |   500  (16)| 00:00:01 |                                       
|   6 |     VIEW               | VW_NSO_1 |   100 |  2500 |       |   499  (16)| 00:00:01 |                                       
|   7 |      SORT GROUP BY     |          |   100 |   300 |       |   499  (16)| 00:00:01 |                                       
|   8 |       TABLE ACCESS FULL| XTABLE   |  1000K|  2929K|       |   434   (3)| 00:00:01 |                                       
-------------------------------------------------------------------------------------------        
请解释为什么我不能信任案例2中的优化器计划

永远不要相信优化器。国会预算办公室95%是正确的,但你不知道哪5%是错误的

典型的问题是,使用EXPLAIN plan显示的执行计划不等于执行所使用的计划。你没有说你是如何得到这个计划的

如有疑问,请使用长时间运行的查询来查看实际计划和有问题的部分

是什么导致优化器忽略线性复杂度和指数复杂度之间的明显差异

请参见上文,忘记计划的成本比较。处理整个表时要避免的是嵌套循环处理。 这正是案例3中发生的情况

 |  3 |     NESTED LOOPS SEMI            |       |   50000|  300000 | 278208956 | 03:01:08|
 |  4 |      TABLE ACCESS FULL           |XTABLE | 1000000| 3000000 |       280 | 00:00:01|
 |  5 |      TABLE ACCESS BY ROWID RANGE |XTABLE |   50000|  150000 |       278 | 00:00:01|
您想看到排序和散列连接这是计划1显示的内容

在我看来,计划2不会随着重复记录的数量而扩展,只需在一个表中每行尝试两次,看看是否得到与案例3相同的运行时间。 优化器无法估计重复记录的数量,因此防御性地估计了较高的数量,从而导致了较高的成本

最后一句话——理论上说你不应该观察线性行为,但最好是在*logn上

最后一句话-对于DUP移除,您的测试数据不现实。通常,您有一个包含少量DUP的大表。在您的设置中,除100条记录外,所有记录都是重复的

删除的成本在查找DUP的成本中占主导地位,因此您可以观察线性行为

试一试

CREATE TABLE xtable(x) AS 
   SELECT ceil(dbms_random.value * 100000000) 
     FROM dual
   CONNECT BY level <= 1000000;

select count(*) total, count(*)- count(distinct x) to_be_deleted from xtable;
     TOTAL TO_BE_DELETED
---------- -------------
   1000000          5083  

因此,您将删除0.5%的记录。现在进行缩放,您将完全观察其他模式。

在案例2中,当您说不能信任优化器计划时,您的意思是什么?是什么让你认为2和3的执行计划是相似的?执行计划3有两个完整的表扫描,由嵌套的半循环连接,然后进行过滤。执行计划2有一个排序,后跟一个筛选器,然后使用该排序筛选完整表扫描的结果。这与第一个执行计划非常相似,IMOH.@ Boeistor,我考虑列值、字节、成本、时间的总值的相似性。令人惊讶的是,它们几乎是一样的,当我们用不同数量的行填充表格时,它们是同步变化的:1000,10000,…,10000加上一个用于准备好的Q。请提供Oracle版本,并将谓词信息添加到解释计划中。看看如何获取信息。它看起来像我期望的那样。似乎我的数据库有一个异常或棘手的设置或其他东西。现在真的没关系了。困扰我的是如何确定DB执行查询的方式。我很困惑,因为我以前从未遇到过这样的问题,并且认为解释计划至少大致显示了查询运行时的预期结果。@diziaq您有什么Oracle版本?我已经在11和12中测试了它,当我们不计算成本时,执行计划是相同的。你永远不会确定。您可以使用SQL计划基线我昨天和今天多次在Oracle 12.1上使用不同的实例获得计划。问了这个问题后,我在Oracle 11.2上尝试了相同的查询,正如您所做的,我无法重现我所问的计划。看起来是个意外,但我想知道是什么原因造成的。谢谢你提供的有用信息。我同意On*logn,但令人惊讶的是结果是100000行:1.65秒;1000000行-15.8行;10000000-138.6秒;甚至比预期的还要低。“我认为低质量的测试数据抵消了常见的理论影响。”迪齐亚克补充道
-------------------------------------------------------------------------------------------                                       
| Id  | Operation              | Name     | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     |                                       
-------------------------------------------------------------------------------------------                                       
|   0 | DELETE STATEMENT       |          |       |       |       |  3648 (100)|          |                                       
|   1 |  DELETE                | XTABLE   |       |       |       |            |          |                                       
|   2 |   MERGE JOIN ANTI NA   |          |   999K|    26M|       |  3648   (5)| 00:00:01 |                                       
|   3 |    SORT JOIN           |          |  1000K|  2929K|    22M|  3147   (3)| 00:00:01 |                                       
|   4 |     TABLE ACCESS FULL  | XTABLE   |  1000K|  2929K|       |   434   (3)| 00:00:01 |                                       
|*  5 |    SORT UNIQUE         |          |   100 |  2500 |       |   500  (16)| 00:00:01 |                                       
|   6 |     VIEW               | VW_NSO_1 |   100 |  2500 |       |   499  (16)| 00:00:01 |                                       
|   7 |      SORT GROUP BY     |          |   100 |   300 |       |   499  (16)| 00:00:01 |                                       
|   8 |       TABLE ACCESS FULL| XTABLE   |  1000K|  2929K|       |   434   (3)| 00:00:01 |                                       
-------------------------------------------------------------------------------------------        
 |  3 |     NESTED LOOPS SEMI            |       |   50000|  300000 | 278208956 | 03:01:08|
 |  4 |      TABLE ACCESS FULL           |XTABLE | 1000000| 3000000 |       280 | 00:00:01|
 |  5 |      TABLE ACCESS BY ROWID RANGE |XTABLE |   50000|  150000 |       278 | 00:00:01|
CREATE TABLE xtable(x) AS 
   SELECT ceil(dbms_random.value * 100000000) 
     FROM dual
   CONNECT BY level <= 1000000;

select count(*) total, count(*)- count(distinct x) to_be_deleted from xtable;
     TOTAL TO_BE_DELETED
---------- -------------
   1000000          5083