Объединяющиеся таблицы с миллионами строк - PullRequest
1 голос
/ 04 октября 2011

У меня есть sql ниже, который возвращает 35 тыс. Строк и занимает около 10 минут для запуска.обе таблицы имеют миллионы строк.Как я могу улучшить этот sql?

SELECT /*+ index(T_DIRECTORY X_DIR) */ 
                 DIRx.dir_id ,                   
                 base.id       
                 FROM T_DIRECTORY DIRx,  T_PERSON base 
                 WHERE 
                   DIRx.id = 26463
                   and DIRx.PERSONID=  base.PERSONID

'| Id  | Operation                    | Name           |'
'-------------------------------------------------------'
'|   0 | SELECT STATEMENT             |                |'
'|   1 |  NESTED LOOPS                |                |'
'|   2 |   TABLE ACCESS BY INDEX ROWID| T_DIRECTORY |'
'|   3 |    INDEX RANGE SCAN          | X_DIRECTORY |'
'|   4 |   TABLE ACCESS BY INDEX ROWID| T_PERSON      |'
'|   5 |    INDEX UNIQUE SCAN         | I_PERSON      |'

Ответы [ 3 ]

3 голосов
/ 04 октября 2011

Во-первых, убедитесь, что у вас есть подходящие индексы для столбцов в предложении where (DIRx.id) и для объединяемой таблицы (base.personid) и что эти индексы анализируются, чтобы они представляли данные в таблице - если нетЕсли проанализировать, Oracle может выполнить полное табличное сканирование, когда вместо этого может использовать индекс.

SELECT INDEX_NAME, 
       NUM_ROWS, 
       LAST_ANALYZED 
  FROM DBA_INDEXES 
 WHERE TABLE_NAME IN ('T_DIRECTORY','T_PERSON');

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

Параллельный запрос

У вас есть несколько процессоров и больше ничего не работает, когда этоSQL выполняется, т. Е. Является ли он частью пакетного процесса или частью онлайн-процесса, который может быть вызван несколько раз одновременно.Если пакетный процесс и у вас несколько процессоров, попробуйте параллельный запрос, но не делайте этого, если это онлайн-программа (например, отчет, использующий параллельный запрос, попытается использовать все доступные процессоры, и производительность может ухудшиться, если он будет выполняться несколько раз одновременно).или если вы запускаете больше параллельных потоков, чем 2 на одно ядро ​​ЦП.

На практике параллельные потоки будут примерно вдвое меньше времени выполнения на 4 потока.

Кластерные таблицы / индексы

Если эти таблицы всегда объединяются таким образом, вы можете рассмотреть кластеризованную таблицу (где oracle будет хранить соединительные строки каждой таблицы в одних и тех же блоках, поэтому не нужно тратить так много времени на поиск объединенной части, но это можетесть недостаток, если вы также часто обращаетесь к одной из таблиц по отдельности.

Context

Рассмотрение запроса в отдельности не всегда дает лучший ответ - делать что-то действительно быстроекогда это может быть не так, не помогает, поэтому посмотрите на контекст, то есть чтоБудете ли вы делать с 35000 возвращенными строками, они добавлены только сегодня, есть ли таблица с подмножеством, которое можно использовать вместо этого?

1 голос
/ 30 июля 2013

"мне пришлось денормализовать таблицу"

В базе данных OLTP денормализация всегда плохая новость.Это ускоряет некоторые запросы, но может замедлять другие.В лучшем случае это приводит к снижению производительности операций DML, а в худшем - к повреждению данных.Это, безусловно, делает наши приложения более сложными.

@ trevorNorth делает правильное замечание о контексте.Распределение данных имеет большое значение.Сколько строк в T_DIRECTORY соответствуют этому идентификатору?Сколько строк в этом наборе результатов имеют совпадающие строки в T_PERSON?Соответствуют ли эти фактические значения количеству элементов в плане объяснения?Если нет, возможно, обновление статистики базы данных позволит базе данных найти лучший план (без подсказки INDEX).Но если ваша статистика актуальна, вам нужно другое решение.

Например ... что?

Настройка - сложная задача, потому что нужно учесть так много вещей, и особенности действительно имеют значение .Некоторые консультанты очень хорошо зарабатывают на жизнь, не делая ничего, кроме исправления ошибок производительности в коде других людей.Они не смогли бы сделать это, если бы настройка была простой.

При отсутствии веских фактов приведу пару догадок.Альтернативные способы решения этой проблемы:

  1. Устранить чтение таблицы и, возможно, также получить хеш-соединение, создав составные индексы:
    T_DIRECTORY(ID, PERSONID, DIR_ID)
    T_PERSON(PERSONID,ID)
  2. Постройте быстрое обновление материализованного представления оператора и разрешите переписывание запросов для удовлетворения запросов.
0 голосов
/ 29 ноября 2011

Мне пришлось денормализовать таблицу.

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