2016-01-02 5 views
0

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

select p.id, p.name, w.id, w.name 
from person p 
inner join work w on w.id = p.wid 
where p.id in (somenumbers) 
vs 

select p.id, p.name, (select id from work where id=p.wid) , (select name from work where id=p.wid) 
from person p 
where p.id in (somenumbers) 

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

+1

Вы используете совместный подзапрос, который не так эффективен, как внутреннее соединение. – SMA

+0

Что это значит и почему это не так –

+2

Я удалил посторонние теги базы данных. Не стесняйтесь добавлять базу данных, которую вы фактически используете. Вопросы производительности часто зависят от базы данных. –

ответ

3

Во-первых, два запроса: не то же самое. Первый отфильтровывает любые строки, которые не имеют соответствующих строк в work.

Эквивалент первый запрос использует left join:

select p.id, p.name, w.id, w.name 
from person p left join 
    work w 
    on w.id = p.wid 
where p.id in (somenumbers); 

Затем второй запрос может быть упрощена:

select p.id, p.name, p.wid, 
     (select name from work where w.id = p.wid) 
from person p 
where p.id in (somenumbers); 

Там нет никаких оснований искать идентификатор в work когда уже присутствует в person.

Если вы хотите оптимизировать запросы, то вам нужны индексы на person(id, wid, name) и work(id, name).

С этими индексами два запроса должны иметь в основном такую ​​же производительность. Подзапрос будет использовать индекс на work для извлечения строк из work, а в предложении where будет использоваться индекс на person. Любой запрос должен быть быстрым и масштабируемым.

+0

поэтому, если я не использовал индексы, то первое утверждение должно быть быстрее и лучше, не так ли? –

+0

@MohemmadAlBughdadi. , , Если у вас нет индексов, обе версии будут излишне медленными на больших объемах данных. Однако у вас, вероятно, есть индекс на 'work (id)', если 'id' объявлен как первичный ключ. –

2

Подзапросы в вашем втором пример выполнит один раз для каждой строки, которая будет работать плохо. Тем не менее, некоторые оптимизаторы могут смогут конвертировать его в соединение для вас - YMMV.

Хорошее правило, которому следует следовать в целом: много предпочитает присоединяться к подзапросам.

+0

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

+0

@MohemmadAlBughdadi no - использование памяти очень эффективно для соединений. – Bohemian

1

Соединения дают лучшую производительность по сравнению с подзапросом .если есть соединение в столбце Int или индексный столбец соединения дает лучшую производительность.

select p.id, p.name, w.id, w.name 
from person p 
inner join work w on w.id = p.wid 
where p.id in (somenumbers) 
Смежные вопросы