Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.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
Sql 第一个查询没有考虑第二个查询的hosen,因为Oracle会选择成本较低的计划_Sql_Performance_Oracle - Fatal编程技术网

Sql 第一个查询没有考虑第二个查询的hosen,因为Oracle会选择成本较低的计划

Sql 第一个查询没有考虑第二个查询的hosen,因为Oracle会选择成本较低的计划,sql,performance,oracle,Sql,Performance,Oracle,添加带有索引提示的USE_NL_不会影响任何计划的成本。它所做的是,如果一个带有索引计划的嵌套循环可用,那么任何其他计划都将被排除在考虑范围之外,即使Oracle认为它们是更有效的计划 其次,“t1.id=t2.id”的谓词允许我们从t1开始并链接到t2,或者从t2开始并链接到t1。将该谓词更改为“t1.id=t2.id+0”意味着它只能从t2(将0添加到id)链接到t1。Oracle不够聪明,没有意识到它可以从t1开始(从id中减去0),然后连接到t2(或者加/减0是不相关的) 这两种技巧都阻

添加带有索引提示的USE_NL_不会影响任何计划的成本。它所做的是,如果一个带有索引计划的嵌套循环可用,那么任何其他计划都将被排除在考虑范围之外,即使Oracle认为它们是更有效的计划

其次,“t1.id=t2.id”的谓词允许我们从t1开始并链接到t2,或者从t2开始并链接到t1。将该谓词更改为“t1.id=t2.id+0”意味着它只能从t2(将0添加到id)链接到t1。Oracle不够聪明,没有意识到它可以从t1开始(从id中减去0),然后连接到t2(或者加/减0是不相关的)

这两种技巧都阻止使用特定的访问路径。两者都不能解释所选计划成本的明显下降

给定“AND t1.version\u id=t2.version\u id”和“AND t1.version\u id=t3.version\u id”,然后 “t3.version\u id=t2.version\u id”是一个给定值(取决于数据类型转换)。但是,显式添加它会向Oracle建议,由于应用了一个额外的条件,因此返回的行会更少,这可能反映在较低的成本上

如果t2和t3版本id不是数字,这可以解释成本的变化。“+0”将强制进行数据类型转换,从而允许使用索引。但我认为这不太可能

我怀疑最初的计划是从t1开始的(t1.id=123,版本名称为“AA”)。额外的谓词(可能)会强制它从t2开始



就我个人而言,我不喜欢任何其他的优化。没有解决最初选择错误计划的原因。

补充Ask Tom已提交的关于使用工具(或其他n步方法)进行调优的答案。

补充Ask Tom已提交的关于使用工具(或其他n步方法)进行调优的答案。

您确定不是
使用带索引的NL\u吗(t1)
hint性能提升了吗?为这两个语句生成计划,我们可能可以找出差异-但第二个查询中的提示可能是最大的改进。@Peter Lang;该工具创建了原始查询的替代方案。一个替代方案只有提示,而它的性能也超过了原始查询首先,上面的查询是“赢家”。您确定它不是
使用带有索引(t1)的\u NL\u吗
hint性能提升了吗?为这两个语句生成计划,我们可能可以找出差异-但第二个查询中的提示可能是最大的改进。@Peter Lang;该工具创建了原始查询的替代方案。一个替代方案只有提示,而它的性能也超过了原始查询很遗憾,上面的问题是“赢家”.+1用于提及统计信息-这看起来像是一个相对简单的连接,我认为优化器会找到原始查询的最佳路径,如果它有正确的信息。@DCookie;是的,version_id和id列都是相同的数据类型。+1用于提及统计信息-这看起来像是一个相对简单的连接d我认为如果优化器有正确的信息,它会为原始查询找到最佳路径。@DCookie;是的,version\u id和id列都是相同的数据类型。@Rob;该工具对执行计划进行了很好的并排比较,所以我知道了那里发生了什么。我不熟悉这些“技巧”这显然对查询性能产生了一些影响,我想知道他们在做什么来提高性能。@Rob;该工具对执行计划进行了很好的并行比较,所以我了解了其中的情况。我不熟悉这些“技巧”这显然对查询性能产生了一些影响,我想知道他们在做什么来提高性能。@Gary:如果提示有效(没有执行计划很难说),您无法比较成本的绝对值它会人为地降低访问路径的成本,以迫使优化器选择它。不,不会。该提示只是阻止考虑其他路径。基数或选择性提示可能会改变成本,但访问路径提示不会。可以使用10053验证trace@Gary:您无法比较成本的绝对值-如果e提示是有效的(如果没有执行计划,很难说),它人为地降低了访问路径的成本,以迫使优化器选择它。不,它不是。该提示只是防止考虑其他路径。基数或选择性提示可能会改变成本,但访问路径提示不会。可以通过10053跟踪进行验证
SELECT t1.version_id, 
       t1.id, 
       t2.field1, 
       t3.person_id, 
       t2.id 
  FROM table1 t1, 
       table2 t2, 
       table3 t3 
 WHERE t1.id = t2.id 
   AND t1.version_id = t2.version_id 
   AND t2.id = 123
   AND t1.version_id = t3.version_id 
   AND t1.VERSION_NAME <> 'AA' 
 order by t1.id
SELECT /*+ USE_NL_WITH_INDEX(t1) */ t1.version_id, 
       t1.id, 
       t2.field1, 
       t3.person_id, 
       t2.id 
  FROM table2 t2, 
       table3 t3,
       table1 t1 
 WHERE t1.id = t2.id + 0
   AND t1.version_id = t2.version_id + 0
   AND t2.id = 123
   AND t1.version_id = t3.version_id + 0
   AND t1.VERSION_NAME || '' <> 'AA' 
   AND t3.version_id = t2.version_id + 0
 order by t1.id
explain plan
for
<your query>;

select * from table(dbms_xplan.display);