#sql #database #performance #oracle #oracle10g
#sql #База данных #Производительность #Oracle #oracle10g
Вопрос:
у меня есть 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 |'
Комментарии:
1. Единственные реальные оптимизации, оставшиеся здесь, находятся на аппаратном уровне. Голосование за переход к serverfault.
2. Попробуйте удалить подсказку index. Если вы возвращаете миллионы строк, сканирование индекса, вероятно, будет медленнее, чем полное сканирование таблицы
Ответ №1:
Во-первых, убедитесь, что у вас есть подходящие индексы для столбцов в предложении 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 будет хранить соединяемые строки каждой таблицы в одних и тех же блоках, чтобы не тратить так много времени на извлечение соединяемой части, но это может иметь недостаток, если вы также часто обращаетесь к одной из таблиц отдельно.
Контекст
Просмотр запроса в изоляции не всегда дает лучший ответ — выполнение чего-то действительно быстрого, когда это может быть неправильно, не помогает, поэтому посмотрите на контекст, т.Е. Что вы будете делать с 35000 строк, которые были возвращены после их возврата, добавлены ли они только сегодня, есть ли таблица, в которой есть подмножество, которое могло быиспользовать вместо этого?
Ответ №2:
«мне пришлось денормализовать таблицу»
В базе данных OLTP де-нормализация всегда является плохой новостью. Это ускоряет некоторые запросы, но может замедлить другие. В лучшем случае это снижает производительность операций DML, в худшем — может привести к повреждению данных. Это, безусловно, усложняет наши приложения.
@trevorNorth справедливо указывает на контекст. Распределение данных имеет большое значение. Сколько строк в T_DIRECTORY соответствует этому идентификатору? Сколько строк в этом результирующем наборе имеют совпадающие строки в T_PERSON ? Соответствуют ли эти фактические значения мощности в плане объяснения? Если нет, возможно, обновление статистики базы данных позволит базе данных найти лучший план (без подсказки ИНДЕКСА). Но если ваша статистика актуальна, вам нужно другое решение.
Например … что?
Настройка — сложная задача, потому что нужно учитывать так много вещей, и особенности действительно важны . Некоторые консультанты прекрасно зарабатывают на жизнь, ничего не делая, кроме исправления ошибок производительности в коде других людей. Они не смогли бы этого сделать, если бы настройка была простой.
В отсутствие неопровержимых фактов вот пара догадок. Альтернативные способы решения этой проблемы:
- Исключите чтение таблицы и, возможно, также получите хэш-соединение, создав составные индексы:
T_DIRECTORY(ID, PERSONID, DIR_ID)
T_PERSON(PERSONID,ID)
- Создайте материализованное представление быстрого обновления для инструкции и разрешите переписывать запросы для удовлетворения запросов.
Ответ №3:
мне пришлось денормализовать таблицу.
Комментарии:
1. Вы объединили всю таблицу? Если вы используете Oracle 11g, вы можете использовать виртуальный столбец (индекс)