2010-12-16 2 views
2

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

select c0.documentid from contentblob as c0 where c0.documentid > ? 
    and c0.blobid = ? 
    and exists (select * from contentblob c1 where c1.documentid = c0.documentid 
       and c1.blobid = ?) 
    order by c0.documentid 

Обратите внимание, что РАЗНЫЕ значения будут поставляться для двух blobid сравнений. То, что делает этот запрос, возвращает идентификаторы, которые встречаются в таблице (по крайней мере) дважды: один раз с blobid1 и один раз с blobid2.

по сравнению с эквивалентным автообъединением,

при условии, конечно, индексы на documentid и blobid столбцах таблицы contentblob.

В случае, если неясно, соответствующая схема здесь представляет собой таблицу с двумя столбцами varchar, documentid и blobid. Они составлены для формирования первичного ключа.

Если для этого нет ничего, кроме как запросить анализатор запросов в db, я сделаю это.

ответ

1

Как правило, коррелируют подзапросы являются более дорогими, чем соединения, даже внешний Самосоединения, хотя в этом случае все, что вам нужно, это регулярная внутренняя автообъединение:

SELECT c0.documentid 
    FROM contentblob AS c0 
    JOIN contentblob AS c1 ON c1.documentid = c0.documentid 
WHERE c0.documentid > ? 
    AND c0.blobid = ? 
    AND c1.blobid = ? 
    AND c0.blobid < c1.blobid 
ORDER BY c0.documentid 

Последнее условие избегает видеть два записи для пары строк с одинаковым идентификатором документа и соответствующими значениями идентификатора ячейки; без него вы увидите идентификатор документа дважды, один раз для c0.blobid = v1 и один раз для c0.blobid = v2.

Возможно, вы захотите переместить условие c1.blobid в предложение ON, но оптимизатор должен сделать это для вас в любом случае. Также проверьте, что ваш оптимизатор использует соответствующий индекс. Не совсем понятно, что это за индекс (но я думаю, что индекс с blobid как ведущий столбец, вероятно, будет работать лучше всего), но если таблицы большие, а оптимизатор использует последовательное сканирование таблицы, у вас есть проблемы ,

0

Я думаю, что левое соединение будет понятнее

select c0.documentid from contentblob as c0 where c0.documentid > ? 
    and c0.blobid = ? 
    left join contentblob c1 on c0.documentid = c1.documentid 
     and c1.blobid = ? 
    order by c0.documentid 

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

+0

См. Править, что я надеюсь, уточнит. Применяются два разных блобида. – bmargulies 2010-12-16 03:27:00