почему оптимизатор oracle не исключил этот случай? - PullRequest
1 голос
/ 20 февраля 2020

Я сомневаюсь в этом случае, но не ясно, почему.

рассмотрим следующее sql:

create table t1(tid int not null, t1 int not null);
create table t2(t2 int not null, tname varchar(30) null);
create unique index i_t2 on t2(t2);
create or replace view v_1 as
select t1.tid,t1.t1,max(t2.tname) as tname
from t1 left join t2
on t1.t1 = t2.t2
group by t1.tid,t1.t1;

, затем проверьте план выполнения для select count (1) из v_1 t2 удаляется оптимизатором:

SQL> select count(1) from v_1;


Execution Plan
----------------------------------------------------------
Plan hash value: 3243658773

----------------------------------------------------------------------------------
| Id  | Operation            | Name      | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------------
|   0 | SELECT STATEMENT     |           |     1 |       |     3  (34)| 00:00:01 |
|   1 |  SORT AGGREGATE      |           |     1 |       |            |          |
|   2 |   VIEW               | VM_NWVW_0 |     1 |       |     3  (34)| 00:00:01 |
|   3 |    HASH GROUP BY     |           |     1 |    26 |     3  (34)| 00:00:01 |
|   4 |     TABLE ACCESS FULL| T1        |     1 |    26 |     2   (0)| 00:00:01 |
----------------------------------------------------------------------------------

, но если индекс i_t2 отбрасывается или воссоздается без уникального атрибута,

таблица t2 не исключается в плане выполнения:

SQL> drop index i_t2;

Index dropped.

SQL> select count(1) from v_1;


Execution Plan
----------------------------------------------------------
Plan hash value: 2710188186

-----------------------------------------------------------------------------------
| Id  | Operation             | Name      | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------------
|   0 | SELECT STATEMENT      |           |     1 |       |     5  (20)| 00:00:01 |
|   1 |  SORT AGGREGATE       |           |     1 |       |            |          |
|   2 |   VIEW                | VM_NWVW_0 |     1 |       |     5  (20)| 00:00:01 |
|   3 |    HASH GROUP BY      |           |     1 |    39 |     5  (20)| 00:00:01 |
|*  4 |     HASH JOIN OUTER   |           |     1 |    39 |     4   (0)| 00:00:01 |
|   5 |      TABLE ACCESS FULL| T1        |     1 |    26 |     2   (0)| 00:00:01 |
|   6 |      TABLE ACCESS FULL| T2        |     1 |    13 |     2   (0)| 00:00:01 |
-----------------------------------------------------------------------------------

похоже, даже если индекс удален,

результат выбора count (1) из v_1 также равен select count (1) из (select tid, t1 из группы t1 по tid , t1)

почему оптимизатор не устраняет t2 во втором случае?

Есть ли какой-либо принцип или пример реальных данных, описывающих это? спасибо:)

1 Ответ

2 голосов
/ 20 февраля 2020

Это оптимизация, называемая устранением соединения. Поскольку t2.t2 уникален, оптимизатор знает, что каждая строка, извлеченная из t1, может извлечь только одну строку из t2. Поскольку от t2 ничего не спроецировано, нет необходимости выполнять соединение. Если вы выполните

select tid, t1 from v_1;

, вы увидите, что мы не выполняем объединение. Однако, если мы проецируем из t2, то соединение необходимо.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...