Два одинаковых стола, но разные соединения - PullRequest
1 голос
/ 15 июня 2019

Я выполняю один и тот же запрос соединения, используя две разные таблицы, но первая (таблица A) истекает, а вторая (таблица B) - нет.

SELECT * FROM table_X
INNER JOIN table_A
ON table_A.point_origin = table_X.item_id
WHERE ROWNUM < 10;

SELECT * FROM table_X
INNER JOIN table_B
ON table_B.point_origin = table_X.item_id
WHERE ROWNUM < 10;

Насколько я знаю, таблица A является подмножеством таблицы B. Ни таблица A, ни таблица B не проиндексированы point_origin.

(Изменить для пояснения: таблица A является только подмножеством таблицы B с точки зрения идентификаторов строк, а не с точки зрения точных данных столбцов.)

Для чего это стоит, яработа с очень большими таблицами, и item_id проиндексирован.

Есть ли что-то еще, что может повлиять на производительность, или я определенно ошибаюсь в представленной информации?

Редактировать: Дополнительная информация для каждого комментария ниже

table_A:

---------------------------------------------------------------------------------------------------------
| Id  | Operation                    | Name                | Rows  | Bytes | Cost (%CPU)| Pstart| Pstop |
---------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |                     |     9 |  4743 |    12   (0)|       |       |
|*  1 |  COUNT STOPKEY               |                     |       |       |            |       |       |
|   2 |   TABLE ACCESS BY INDEX ROWID| table_X             |     1 |   227 |     1   (0)|       |       |
|   3 |    NESTED LOOPS              |                     |    11 |  5797 |    12   (0)|       |       |
|   4 |     PARTITION RANGE ALL      |                     |    10M|  2969M|     2   (0)|     1 |     4 |
|   5 |      TABLE ACCESS FULL       | table_A             |    10M|  2969M|     2   (0)|     1 |     4 |
|*  6 |     INDEX RANGE SCAN         | table_X_IP_PK       |     1 |       |     1   (0)|       |       |
---------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter(ROWNUM<10)
   6 - access("table_A"."POINT_ORIGIN"="table_X"."ITEM_ID")

Note
-----
   - 'PLAN_TABLE' is old version

table_B:

-----------------------------------------------------------------------------------------
| Id  | Operation                    | Name                | Rows  | Bytes | Cost (%CPU)|
-----------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |                     |     9 |  3879 |    11   (0)|
|*  1 |  COUNT STOPKEY               |                     |       |       |            |
|   2 |   TABLE ACCESS BY INDEX ROWID| table_X             |     1 |   227 |     1   (0)|
|   3 |    NESTED LOOPS              |                     |    10 |  4310 |    11   (0)|
|   4 |     TABLE ACCESS FULL        | table_B             |   118M|    22G|     2   (0)|
|*  5 |     INDEX RANGE SCAN         | table_X_IP_PK       |     1 |       |     1   (0)|
-----------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter(ROWNUM<10)
   5 - access("table_B"."POINT_ORIGIN"="table_X"."ITEM_ID")

Note
-----
   - 'PLAN_TABLE' is old version

1 Ответ

0 голосов
/ 15 июня 2019

Похоже, что table_a разбит на разделы и что запрос должен сканировать только 4 раздела, тогда как table_b не разбит на разделы и должен быть прочитан полностью. По оценкам оптимизатора, 4 раздела table_a имеют 10 миллионов строк, а table_b - 118 миллионов строк. Вы используете вложенный цикл, так что вы ожидаете, что производительность O (n), основанная на статистике, будет иметь смысл, что второй запрос будет занимать ~ 11,8 раза дольше, чем первый запрос.

Точны ли оценки оптимизатора? Оптимизатор работает только с той статистикой, которую вы ему предоставили, и возможно, что одна или обе таблицы имеют устаревшую статистику.

...