Производительность: подзапрос или соединение - PullRequest
5 голосов
/ 20 мая 2010

У меня небольшой вопрос по поводу выполнения подзапроса / присоединения к другой таблице

INSERT
INTO Original.Person
  (
    PID, Name, Surname, SID
  )
  (
    SELECT ma.PID_new , TBL.Name , ma.Surname, TBL.SID 
    FROM Copy.Person TBL , original.MATabelle MA
    WHERE TBL.PID         = p_PID_old
      AND TBL.PID         = MA.PID_old
  );

Это мой SQL, теперь эта штука работает около 1 миллиона раз или больше. У меня вопрос, что будет быстрее?

  • Если я изменю TBL.SID на (Select new from helptable where old = tbl.sid)

ИЛИ

  • Если я добавлю 'HelpTable' к from и выполню объединение в where?

edit1
Ну, этот скрипт работает только столько, сколько существует человек.

В моей программе 2 модуля, один из которых заполнен MaTabelle, а другой - для передачи данных. Эта программа объединяет 2 базы данных вместе, и иногда используется один и тот же ключ.
Сейчас я работаю над решением, что дублирующих ключей не существует.

Мое решение - создать «HelpTable». Владелец ключа (SID) создает новый ключ и записывает его в «HelpTable». Все остальные таблицы, использующие этот ключ, могут читать его из таблицы «HelpTable».

edit2
Просто у меня в голове что-то есть:
если таблица в качестве ключа, который может быть нулевым (иностранный ключ, который не связан) тогда это не будет работать с from или?

Ответы [ 4 ]

7 голосов
/ 20 мая 2010

Современные RDBM, включая Oracle, оптимизируют большинство соединений и подзапросов до одного и того же плана выполнения.

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

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

Редактировать

Вот несколько общих советов, применимых к вашему запросу:

  • Для объединений убедитесь, что у вас есть индекс для столбцов, к которым вы присоединяетесь. Обязательно примените индекс к объединенным столбцам в обеих таблицах. Вы можете подумать, что вам нужен индекс только в одном направлении, но вы должны индексировать оба, поскольку иногда база данных определяет, что лучше объединиться в противоположном направлении.
  • Для предложений WHERE убедитесь, что у вас есть индексы для столбцов, упомянутых в WHERE.
  • Для вставки множества строк лучше всего вставить их все в один запрос.
  • Для вставки в таблицу с кластеризованным индексом лучше, если вы вставляете инкрементные значения для кластеризованного индекса, чтобы новые строки добавлялись в конец данных. Это позволяет избежать перестроения индекса и часто избегает блокировок существующих записей, что замедляет запросы SELECT к существующим строкам. По сути, вставки становятся менее болезненными для других пользователей системы.
3 голосов
/ 20 мая 2010

Присоединение будет намного быстрее, чем подзапрос

2 голосов
/ 20 мая 2010

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

Кроме того, это присоединяется к подзапросу может дать вам больше информации

0 голосов
/ 20 мая 2010

Вместо того, чтобы сосредоточиться на том, использовать ли соединение или подзапрос, я бы сосредоточился на необходимости выполнения 1 000 000 выполнений этого конкретного оператора вставки. Тем более, что оптимизатор Oracle, как уже отмечал Маркус Адамс, оптимизирует и переписывает ваши заявления под прикрытием в наиболее оптимальной форме.

Вы заполняете MaTabelle 1 000 000 раз всего несколькими строками и выполняете это утверждение? Если да, то ответ - сделать это одним выстрелом. Можете ли вы предоставить больше информации о вашем процессе, который выполняет это утверждение так много раз?

РЕДАКТИРОВАТЬ: Вы указываете, что этот оператор вставки выполняется для каждого человека. В этом случае рекомендуется сначала заполнить MATabelle, а затем выполнить один раз:

INSERT 
INTO Original.Person 
  ( 
    PID, Name, Surname, SID 
  ) 
  ( 
    SELECT ma.PID_new , TBL.Name , ma.Surname, TBL.SID  
    FROM Copy.Person TBL , original.MATabelle MA 
    WHERE TBL.PID         = MA.PID_old 
  );

С уважением, Роб.

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