我需要一些帮助来解决如何提高查询效率的方法。我不是SQL的专家,但我已经对此有所了解,但我正处于需要讨论/讨论的地步。
我有以下查询:
SELECT * FROM
(
SELECT
a.seq_num seq_num_a,
a.record_length record_length_a,
b.record_length record_length_b,
c.record_length record_length_c
a.deleted deleted_a,
b.deleted deleted_b,
c.deleted deleted_c
FROM tableA a
INNER JOIN tableB b
ON a.reference = b.reference
AND a.run_id = b.run_id
INNER JOIN tableC c
ON a.reference = c.reference
AND a.run_id = c.run_id
WHERE a.run_id = 1
)
WHERE deleted_a = 'N'
AND deleted_b = 'N'
AND deleted_c = 'N'
ORDER BY seq_num_a;
一旦我检查到deleted ='N',查询就会很慢 - 即使只是tableA。我将整个查询包装在SELECT中,认为子查询将返回数据集,然后它将是一个简单的检查和顺序。请注意,子查询中的检查没有性能差异。
在所有表中都存在针对run_id和删除的索引,并且针对tableA中的seq_num。每个表中大约有8000行。
查询计划
--------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost |
--------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 112 | 7 |
| 1 | SORT ORDER BY | | 1 | 112 | 7 |
| 2 | NESTED LOOPS | | 1 | 112 | 3 |
| 3 | NESTED LOOPS | | 1 | 79 | 2 |
| 4 | TABLE ACCESS BY INDEX ROWID| TABLEC | 1 | 33 | 2 |
|* 5 | INDEX SKIP SCAN | TABLEC_IDX2 | 1 | | 2 |
|* 6 | TABLE ACCESS BY INDEX ROWID| TABLEA | 1 | 46 | |
|* 7 | INDEX RANGE SCAN | TABLEA_IDX5 | 1 | | |
|* 8 | TABLE ACCESS BY INDEX ROWID | TABLEB | 1 | 33 | 1 |
|* 9 | INDEX UNIQUE SCAN | TABLEB_PK | 1 | | |
--------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
5 - access("C"."DELETED"='N')
filter("C"."DELETED"='N')
6 - filter("A"."REFERENCE"="C"."REFERENCE" AND
"A"."RUN_ID"="C"."RUN_ID")
7 - access("A"."DELETED"='N')
8 - filter("B"."DELETED"='N')
9 - access("A"."RUN_ID"="B"."RUN_ID" AND
"A"."REFERENCE"="B"."REFERENCE")
Note: cpu costing is off
答案 0 :(得分:0)
不确定外部选择提供什么值..根据oracle的版本,解释计划可能不同。但是在旧版本中,我发现在连接之前限制数据会大大提高性能。
因此从A开始并且获得最少量的记录以加入b然后到C比开始使用所有A,加入所有b并加入所有C然后通过where子句减少结果要快得多...但是后来查询优化器的版本考虑到了这一点,所以没有收获...那么......什么版本的oracle?
SELECT
a.seq_num seq_num_a,
a.record_length record_length_a,
b.record_length record_length_b,
c.record_length record_length_c
a.deleted deleted_a,
b.deleted deleted_b,
c.deleted deleted_c
FROM tableA a
INNER JOIN tableB b
ON a.reference = b.reference
AND a.run_id = b.run_id
AND a.deleted = 'N'
and b.deleted = 'N'
and a.run_ID = 1
INNER JOIN tableC c
ON a.reference = c.reference
AND a.run_id = c.run_id
and c.deleted = 'N'
ORDER BY seq_num_a;