2010-05-20 3 views
4

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

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
Только что-то в моей голове:
если таблица как ключ, который может быть нулевым (ForeignKey, что не связано) то это не будет работать с с или?

ответ

7

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

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

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

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

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

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

Хорошо, чтобы обеспечить мою схему db, невозможно залить его круглыми 100 столами или более, и его трудно понять. Теперь я посмотрю, что я буду делать. – domiSchenk

+0

Нам не нужна вся ваша схема, только таблицы, указанные в запросе. –

+0

Хорошо, используя теперь подзапрос, его проще сделать thx для вашей помощи. – domiSchenk

3

Объединение было бы гораздо быстрее, чем подзапрос

+0

Это он только что должен прочитать таблицу? – domiSchenk

+3

Поскольку в подзапросе сначала создается временная таблица, а затем она будет соединена. –

2

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

Кроме того, это joins vs subquery может дать вам некоторую информацию

0

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

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

EDIT: Вы указываете, что этот оператор вставки выполняется для каждого человека. В этом случае совет должен сначала заполнить 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 
); 

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

+0

Просмотреть первое сообщение изменить: D – domiSchenk

Смежные вопросы