Мне интересно, почему MS SQL Server Query Planner создает вложенные циклы, а не выбирает Union для JOIN с условиями OR.ПРИСОЕДИНЯЙТЕСЬ с ИЛИ - Планировщиком запросов Выбор вложенных циклов
Примечание: Из поиска на SO, не кажется, MSSQL конкретные
Э.Г.
SELECT * FROM TableA a
JOIN TableB b
ON a.One = b.One
OR a.Two = b.Two
Принимает 6 минут в моем случае (И один и два индексируются на обеих таблицах)
Но
SELECT * FROM TableA a
JOIN TableB b
ON a.One = b.One
UNION -- Not ALL, as need to remove duplicates
SELECT * FROM TableA a
JOIN TableB b
ON a.Two = b.Two
занимает 2 секунды.
Я знаю причину, по которой первое занимает так много времени (из-за вложенного цикла, где в качестве 2-х союзов используются индексы), но мне интересно, почему планировщик запросов не выбирает UNION в качестве плана выполнения?
Есть ли какое-то предостережение, о котором я должен знать при использовании UNION, для которого он не используется?
Почему эта логика не реализована в планировщике запросов?
Следует ли просто упростить код планировщика запросов (как его, вероятно, уже довольно сложный), что-то, что у них не было оптимизировано, или потому что есть некоторые другие оговорки, о которых я не знаю?
@RhysJones очень правилен, иногда использование индексов замедляет вас из-за того, что при использовании некластеризованного индекса ему все равно придется искать кластерный индекс для данных. Так что здесь избирательность играет определенную роль. Другая проблема может быть более обыденной, но статистика может быть устаревшей. Когда последнее обновление статистики? – Namphibian
Эти запросы не эквивалентны. Если 'TableA' или' TableB' содержат дубликаты своих * собственных *, первый запрос вернет их, второй запрос не будет. Оптимизатор не может переписать один на другой в целом. –
@jeroen Это просто нужно использовать rid как дедупификатор, как это уже делается в некоторых случаях http://blogs.msdn.com/b/craigfr/archive/2006/08/30/732409.aspx –