【发布时间】:2014-10-09 07:54:53
【问题描述】:
我有一个查询耗时过长,即 60 分钟。我是程序员,但我不太确定所有表是否都是索引。
这里是查询,任何以_V结尾的表都是视图:
SELECT prod_eff.facility
, prod_eff.product
, (SELECT MIN (cbv1.bucket_header)
FROM AMD_OARS.CURRENT_BUCKETS_V cbv1
WHERE cbv1.version_id = 1
AND cbv1.min_datetime >= prod_eff.EFF_START_DATETIME
) min_eff
, (SELECT MAX (cbv1.bucket_header)
FROM AMD_OARS.CURRENT_BUCKETS_V cbv1
WHERE cbv1.version_id = 1
AND cbv1.min_datetime < prod_eff.EFF_END_DATETIME
) max_eff
, 1 valid
FROM (
SELECT pf.product
, pf.facility
, pf.eff_start_datetime
, pf.eff_end_datetime
FROM AMD_OARS.BOM_PRODUCT_FACILITY pf
, AMD_OARS.MASTER_FACILITY f
WHERE pf.version_id = 114847
AND pf.facility = f.facility
AND f.facility != 'NONE'
AND f.validated = 1
) prod_eff
, AMD_OARS.TEMP_SELECTED_PRODUCT tsp
WHERE tsp.product = prod_eff.product
AND (prod_eff.EFF_START_DATETIME BETWEEN
to_timestamp('07/27/2014 00:00:01.000', 'mm/dd/yyyy hh24:mi:ss.ff3') AND
to_timestamp('12/20/2015 00:00:00.000', 'mm/dd/yyyy hh24:mi:ss.ff3') OR
prod_eff.EFF_END_DATETIME BETWEEN
to_timestamp('07/27/2014 00:00:01.000', 'mm/dd/yyyy hh24:mi:ss.ff3') AND
to_timestamp('12/20/2015 00:00:00.000', 'mm/dd/yyyy hh24:mi:ss.ff3')
)
ORDER BY 1, 2, 3, 4 ;
这是我用来确定某些表是否为索引的查询。
select table_name
from dba_tables
where (owner, table_name) not in (select table_owner, table_name from dba_indexes)
and table_name = 'TEMP_SELECTED_PRODUCT';
对不起,我是数据库方面的新手。我只知道 sql join 和编写基本查询之类的基本知识。任何帮助将不胜感激。我正在使用 Oracle SQL Developer。
如果我做错了什么,有人可以指导我吗?我会很感激。
更新: 我看到this video 了解如何执行“解释计划”,这就是我得到的结果
Plan hash value: 1792060973
-------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 78 | 4 (25)| 00:00:01 |
| 1 | SORT AGGREGATE | | 1 | 66 | | |
|* 2 | TABLE ACCESS BY INDEX ROWID | TEMP_CURRENT_BUCKETS | 1 | 66 | 1 (0)| 00:00:01 |
|* 3 | INDEX RANGE SCAN | TCB_PK | 1 | | 1 (0)| 00:00:01 |
| 4 | SORT AGGREGATE | | 1 | 66 | | |
|* 5 | TABLE ACCESS BY INDEX ROWID | TEMP_CURRENT_BUCKETS | 1 | 66 | 1 (0)| 00:00:01 |
|* 6 | INDEX RANGE SCAN | TCB_PK | 1 | | 1 (0)| 00:00:01 |
| 7 | SORT ORDER BY | | 1 | 78 | 4 (25)| 00:00:01 |
| 8 | NESTED LOOPS | | 1 | 78 | 3 (0)| 00:00:01 |
| 9 | NESTED LOOPS | | 1 | 69 | 2 (0)| 00:00:01 |
| 10 | INDEX FULL SCAN | TSP_PK | 1 | 18 | 1 (0)| 00:00:01 |
|* 11 | TABLE ACCESS BY INDEX ROWID| BOM_PRODUCT_FACILITY | 1 | 51 | 1 (0)| 00:00:01 |
|* 12 | INDEX RANGE SCAN | BPF_PK | 1 | | 1 (0)| 00:00:01 |
|* 13 | TABLE ACCESS BY INDEX ROWID | MASTER_FACILITY | 1 | 9 | 1 (0)| 00:00:01 |
|* 14 | INDEX UNIQUE SCAN | MF_F_PK | 1 | | 1 (0)| 00:00:01 |
-------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - filter("CB"."MIN_DATETIME">=:B1)
3 - access("CB"."VERSION_ID"=1)
5 - filter("CB"."MIN_DATETIME"<:B1)
6 - access("CB"."VERSION_ID"=1)
11 - filter(INTERNAL_FUNCTION("PF"."EFF_START_DATETIME")>=TIMESTAMP' 2014-07-27
00:00:01.000000000' AND INTERNAL_FUNCTION("PF"."EFF_START_DATETIME")<=TIMESTAMP' 2015-12-20
00:00:00.000000000' OR INTERNAL_FUNCTION("PF"."EFF_END_DATETIME")>=TIMESTAMP' 2014-07-27
00:00:01.000000000' AND INTERNAL_FUNCTION("PF"."EFF_END_DATETIME")<=TIMESTAMP' 2015-12-20
00:00:00.000000000')
12 - access("PF"."VERSION_ID"=114847 AND "TSP"."PRODUCT"="PF"."PRODUCT")
filter("TSP"."PRODUCT"="PF"."PRODUCT" AND "PF"."FACILITY"<>'NONE')
13 - filter("F"."VALIDATED"=1)
14 - access("PF"."FACILITY"="F"."FACILITY")
filter("F"."FACILITY"<>'NONE')
【问题讨论】:
-
向我们展示执行计划。
-
我不知道你是什么意思?我浏览了视图内的每个查询并检查它是否被索引?但我很困惑 dba_indexes 和 user_indexes 之间有什么区别
-
索引不会神奇地提高应用程序的性能,如果没有索引的方式更快,Oracle 不会使用它。首先你要收集statistics,其次生成一个explain plan,最后,show是解释计划
-
@Jiten 您可以在此处了解 11g 的解释计划以及如何执行这些计划,docs.oracle.com/cd/E11882_01/server.112/e41573/…。
-
@JitenK 你收集统计数据了吗?我看不出有什么会损害你的表现
标签: sql oracle oracle11g indexing oracle-sqldeveloper