У меня есть таблица (MainTable
) с бит более 600 000 записей. Он присоединяется к себе через вторую таблицу (JoinTable
) в отношении отношения родительского/дочернего типа:
SELECT Child.ID, Parent.ID
FROM MainTable
AS Child
JOIN JoinTable
ON Child.ID = JoinTable.ID
JOIN MainTable
AS Parent
ON Parent.ID = JoinTable.ParentID
AND Parent.SomeOtherData = Child.SomeOtherData
Я знаю, что каждая дочерняя запись имеет родительскую запись, а данные в JoinTable - явные.
Когда я запускаю этот запрос, он занимает буквально минуты для запуска. Однако, если я присоединяюсь к Parent, используя Left Join, тогда он принимает < 1 секунда для запуска:
SELECT Child.ID, Parent.ID
FROM MainTable
AS Child
JOIN JoinTable
ON Child.ID = JoinTable.ID
LEFT JOIN MainTable
AS Parent
ON Parent.ID = JoinTable.ParentID
AND Parent.SomeOtherData = Child.SomeOtherData
WHERE ...[some info to make sure we don't select parent records in the child dataset]...
Я понимаю разницу в результатах между INNER JOIN
и a LEFT JOIN
. В этом случае он возвращает точно такой же результат, как и каждый ребенок имеет родителя. Если я позволю обоим запросам запустить, я смогу сравнить наборы данных, и они будут точно такими же.
Почему он LEFT JOIN
работает намного быстрее, чем INNER JOIN
?
UPDATE Проверяли планы запросов, и при использовании внутреннего соединения он начинается с набора данных родителя. При выполнении левого соединения начинается с набора данных для детей.
Используемые индексы одинаковы.
Могу ли я заставить его всегда начинать с ребенка? Используя левое соединение, он просто чувствует себя не так.
Подобные вопросы задавались здесь раньше, но никто, кажется, не отвечает на мой вопрос.
например. выбранный ответ в INNER JOIN vs LEFT JOIN производительности в SQL Server говорит, что Left Joins всегда медленнее, чем Inner join. Аргумент имеет смысл, но это не то, что я вижу.