Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/9.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/wix/2.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
Performance Oracle日期索引速度慢。如果没有它,查询速度将提高300倍_Performance_Oracle_Date_Indexing_Query Optimization - Fatal编程技术网

Performance Oracle日期索引速度慢。如果没有它,查询速度将提高300倍

Performance Oracle日期索引速度慢。如果没有它,查询速度将提高300倍,performance,oracle,date,indexing,query-optimization,Performance,Oracle,Date,Indexing,Query Optimization,我有一个Oracle查询,运行时间为10分钟或更长,如下所示: select r.range_text as duration_range, nvl(count(c.call_duration),0) as calls, nvl(SUM(call_duration),0) as total_duration from call_duration_ranges r left join big_table c

我有一个Oracle查询,运行时间为10分钟或更长,如下所示:

  select
      r.range_text as duration_range,
      nvl(count(c.call_duration),0) as calls,
      nvl(SUM(call_duration),0) as total_duration
      from
      call_duration_ranges r
      left join
      big_table c
      on c.call_duration BETWEEN r.range_lbound AND r.range_ubound
 and c.aaep_src = 'MAIN_SOURCE'
 and c.calltimestamp_local  >= to_date('01-02-2014 00:00:00' ,'dd-MM-yyyy HH24:mi:ss')
 AND c.calltimestamp_local <=  to_date('28-02-2014 23:59:59','dd-MM-yyyy HH24:mi:ss')
 and          c.destinationnumber LIKE substr( 'abc:1301@company.com:5060;user=phone',1,8) || '%'    
 group by
      r.range_text
 order by
      r.range_text
使用destinationnumber索引查询2天:

0   SELECT STATEMENT            ALL_ROWS    329382  1218    14
1   SORT    GROUP BY            329382  1218    14
2   MERGE JOIN  OUTER           329381  1218    14
3   SORT    JOIN            4   308 14
4   TABLE ACCESS    FULL    CALL_DURATION_RANGES    ANALYZED    3   308 14
5   FILTER                      
6   SORT    JOIN            329377  65  1
7   TABLE ACCESS    BY GLOBAL INDEX ROWID   BIG_TABLE   ANALYZED    329376  65  1
8   INDEX   RANGE SCAN  IDX_CDR_CALLTIMESTAMP_LOCAL ANALYZED    1104        342104
0   SELECT STATEMENT            ALL_ROWS    11  1218    14
1   SORT    GROUP BY            11  1218    14
2   MERGE JOIN  OUTER           10  1218    14
3   SORT    JOIN            4   308 14
4   TABLE ACCESS    FULL    CALL_DURATION_RANGES    ANALYZED    3   308 14
5   FILTER                      
6   SORT    JOIN            6   65  1
7   TABLE ACCESS    BY GLOBAL INDEX ROWID   BIG_TABLE   ANALYZED    5   65  1
8   INDEX   RANGE SCAN  IDX_DESTINATIONNUMBER_PART  ANALYZED    4       4
查询一个月,取消destinationnumber索引--完全扫描:

0   SELECT STATEMENT            ALL_ROWS    824174  1218    14
1   SORT    GROUP BY            824174  1218    14
2   MERGE JOIN  OUTER           824173  1218    14
3   SORT    JOIN            4   308 14
4   TABLE ACCESS    FULL    CALL_DURATION_RANGES    ANALYZED    3   308 14
5   FILTER                      
6   SORT    JOIN            824169  65  1
7   PARTITION RANGE ALL         824168  65  1
8   TABLE ACCESS    FULL    BIG_TABLE   ANALYZED    824168  65  1
不过,这似乎与直觉相反——指数让事情变得如此缓慢

只有当您不了解索引是如何工作的时,才会违反直觉

索引对于检索单个行很有用。它们不适合检索大量记录。您没有费心提供任何指标,但您的查询似乎涉及了大量行。在这种情况下,全表扫描或其他基于set=的操作将更加有效


调整日期范围查询很棘手,因为数据库很难知道有多少记录位于这两个界限之间,无论我们的统计数据是多么最新。(当日期界限可能发生变化时,调整更为棘手——一天与一个月或一年是不同的事情。)因此,我们经常需要利用我们对数据的了解来帮助优化器

不要认为使用“+0”是未来最好的解决方案

为什么不呢?几十年来,人们一直在使用这种技术来避免在特定查询中使用索引

然而,有更多的现代解决方案。未记录的基数提示是:

 select /*+ cardinality(big_table,10000) */ 
。。。应该足以阻止优化器使用索引-前提是您为查询中的所有表收集了准确的统计数据

或者,您可以强制优化器使用

 select /*+ full(big_table) */ 
无论如何,您无法对索引执行任何操作来更改数据库的工作方式。分区可以让事情变得更快,但我想如果你的组织购买了这个软件,你可能已经在使用它了

不过,这似乎与直觉相反——指数让事情变得如此缓慢

只有当您不了解索引是如何工作的时,才会违反直觉

索引对于检索单个行很有用。它们不适合检索大量记录。您没有费心提供任何指标,但您的查询似乎涉及了大量行。在这种情况下,全表扫描或其他基于set=的操作将更加有效


调整日期范围查询很棘手,因为数据库很难知道有多少记录位于这两个界限之间,无论我们的统计数据是多么最新。(当日期界限可能发生变化时,调整更为棘手——一天与一个月或一年是不同的事情。)因此,我们经常需要利用我们对数据的了解来帮助优化器

不要认为使用“+0”是未来最好的解决方案

为什么不呢?几十年来,人们一直在使用这种技术来避免在特定查询中使用索引

然而,有更多的现代解决方案。未记录的基数提示是:

 select /*+ cardinality(big_table,10000) */ 
。。。应该足以阻止优化器使用索引-前提是您为查询中的所有表收集了准确的统计数据

或者,您可以强制优化器使用

 select /*+ full(big_table) */ 

无论如何,您无法对索引执行任何操作来更改数据库的工作方式。分区可以让事情变得更快,但我想如果您的组织购买了,您可能已经在使用它了。

以下是使用索引减慢查询速度的原因:

  • 一个完整的表可以更快。如果必须检索大部分行,则会发生这种情况。具体的数字取决于各种因素,但根据经验法则,如果检索的行数超过10-20%,则在常见情况下使用索引的速度会较慢

  • 使用另一个索引会更好,因为在第一阶段之后剩下的行更少。在表上使用某个索引通常意味着不能使用其他索引

  • 现在,优化器的任务是决定哪种变体是最好的。要执行此任务,他必须猜测(除其他外)在应用某些筛选子句后剩下多少行。这个估计是基于统计表的,通常是很正常的。它甚至考虑了扭曲的数据,但如果你的统计数据已经过时,或者你的数据分布相当不寻常,它可能会被关闭。例如,如果您在示例中插入2月数据之前计算了统计数据,那么优化器可能会错误地得出结论,即在应用日期范围过滤器后,只剩下很少(如果有的话)行

    根据您的数据,在多个列上使用组合索引也可能是一个选项

    关于“扭曲数据问题”的另一个注意事项是:如果在cloumn A上有索引,那么优化器会在列A中检测扭曲数据,但如果在列A和B上只有组合索引,则不会检测,因为组合可能会使分布更加均匀。这是A,B上的索引不使A上的索引成为冗余索引的少数情况之一


    APCs answer展示了如果优化器在正确的统计数据下仍然生成错误的计划,如何使用提示将其引导到正确的方向。

    以下是使用索引减慢查询速度的原因:

  • 一个完整的表可以更快。如果必须检索大部分行,则会发生这种情况。具体的数字取决于各种因素,但根据经验法则,如果检索的行数超过10-20%,则在常见情况下使用索引的速度会较慢

  • 使用另一个索引会更好,因为在第一阶段之后剩下的行更少。在表上使用某个索引通常意味着不能使用其他索引

  • 现在,优化器的任务是决定哪种变体是最好的。要执行此任务,他必须猜测(除其他外)在应用某些筛选子句后剩下多少行。Th