Как соединения базы данных (оракула) обрабатывают состояние фильтра - PullRequest
0 голосов
/ 21 сентября 2011

Когда мы создадим объединение между двумя таблицами в Oracle, с некоторыми дополнительными условиями фильтрации для одной или обеих таблиц, оракул сначала объединит таблицы, а затем отфильтрует или сначала отфильтрует условия, а затем объединит.

Или простыми словами, какой из этих 2 является лучшим запросом

Допустим, у нас есть 2 таблицы «Сотрудник» и «Отдел», и я хочу, чтобы все сотрудники были сотрудниками + подробная информация о отделе, где зарплата сотрудников превышает 50000

Запрос 1: выберите e.name, d.name от сотрудника e, отдел d, где e.dept_id = d.id и e.salary> 50000;

Запрос 2: выберите e.name, d.name из (выберите * у сотрудника, где зарплата> 50000) e, отдел d, где e.dept_id = d.id;

1 Ответ

5 голосов
/ 21 сентября 2011

Как правило, сначала он отфильтрует как можно больше.Из плана объяснения вы можете увидеть, где выполняется фильтрация и где выполняется объединение, например, создайте несколько таблиц и данных:

create table employees (id integer, dept_id integer, salary number);

create table dept (id integer, dept_name varchar2(10));

insert into dept values (1, 'IT');

insert into dept values (2, 'HR');

insert into employees
select level, mod(level, 2) + 1, level * 1000
from dual connect by level <= 100;

create index employee_uk1 on employees (id);

create index dept_uk1 on dept (id);

exec dbms_stats.gather_table_stats(user, 'DEPT');

Теперь, если я объясню оба предоставленных вами запроса,вы обнаружите, что Oracle преобразует каждый запрос в один и тот же план за кулисами (он не всегда выполняет то, что вы думаете - Oracle имеет лицензию на «переписывание» запроса, и он делает это много):

explain plan for
select e.*, d.*
from employees e, dept d
where e.dept_id = d.id
and e.salary > 5000;

select * from table(dbms_xplan.display());

    ------------------------------------------------------------------------------------------
| Id  | Operation                    | Name      | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |           |    96 |  1536 |     6  (17)| 00:00:01 |
|   1 |  MERGE JOIN                  |           |    96 |  1536 |     6  (17)| 00:00:01 |
|   2 |   TABLE ACCESS BY INDEX ROWID| DEPT      |     2 |    12 |     2   (0)| 00:00:01 |
|   3 |    INDEX FULL SCAN           | DEPT_UK1  |     2 |       |     1   (0)| 00:00:01 |
|*  4 |   SORT JOIN                  |           |    96 |   960 |     4  (25)| 00:00:01 |
|*  5 |    TABLE ACCESS FULL         | EMPLOYEES |    96 |   960 |     3   (0)| 00:00:01 |

4 - access("E"."DEPT_ID"="D"."ID")
    filter("E"."DEPT_ID"="D"."ID")
5 - filter("E"."SALARY">5000)

Обратите внимание на операции фильтрации, примененные к запросу.Теперь объясните альтернативный запрос:

explain plan for
select e.*, d.*
from (select * from employees where salary > 5000) e, dept d
where e.dept_id = d.id;

------------------------------------------------------------------------------------------
| Id  | Operation                    | Name      | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |           |    96 |  1536 |     6  (17)| 00:00:01 |
|   1 |  MERGE JOIN                  |           |    96 |  1536 |     6  (17)| 00:00:01 |
|   2 |   TABLE ACCESS BY INDEX ROWID| DEPT      |     2 |    12 |     2   (0)| 00:00:01 |
|   3 |    INDEX FULL SCAN           | DEPT_UK1  |     2 |       |     1   (0)| 00:00:01 |
|*  4 |   SORT JOIN                  |           |    96 |   960 |     4  (25)| 00:00:01 |
|*  5 |    TABLE ACCESS FULL         | EMPLOYEES |    96 |   960 |     3   (0)| 00:00:01 |    

4 - access("EMPLOYEES"."DEPT_ID"="D"."ID")
    filter("EMPLOYEES"."DEPT_ID"="D"."ID")
5 - filter("SALARY">5000)

После того, как вы узнаете, как получить планы объяснения и как их прочитать, вы, как правило, можете понять, что делает Oracle, выполняя ваш запрос.

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