SQL Server: интеллектуальный анализатор с несколькими индексами для одной таблицы в запросе UNION ALL - PullRequest
0 голосов
/ 03 декабря 2018

Я пытаюсь написать запрос для довольно большой таблицы (10 миллионов и более - типичный размер), результат которой необходимо фильтровать по различным предикатам / условиям на основе некоторой бизнес-логики.Мой вопрос: оптимизатор запросов (в SQL Server 2008+) пытается использовать один индекс для всего запроса или пытается использовать разные индексы для каждого запроса?

Примите во внимание следующее:

--Use Index A
SELECT Set1 
FROM ATable
WHERE AColumn = sarg-able value

UNION ALL

--Are we stuck with Index A?
SELECT Set2 
FROM ATable
WHERE BColumn = sarg-able value

Если мы выберем Индекс A для Set1, застряли ли мы с Индексом A для всего запроса, или достаточно ли у оптимизатора достаточно умного, чтобы использовать другой индекс для Set2 (при условии, что одинсуществует)?

Ответы [ 2 ]

0 голосов
/ 04 декабря 2018

Все, что сказал @andreyNikolov, на 100% правильно.Это то, что вы можете легко выяснить самостоятельно, просмотрев Фактический план выполнения (Не Предполагаемый План выполнения).Обратите внимание на следующие примеры данных, таблицу и структуру индекса:

USE tempdb -- safe place in Dev to test this kind of thing...
GO

-- sample data and indexes
IF OBJECT_ID('dbo.ATable','U') IS NOT NULL DROP TABLE dbo.ATable
CREATE TABLE dbo.ATable
(
  Set1    INT NOT NULL,
  Set2    INT NOT NULL,
  AColumn INT NOT NULL,
  BColumn INT NOT NULL
);

INSERT dbo.ATable (Set1, Set2, AColumn, BColumn)
VALUES (1,2,3,3),(1,2,4,4),(5,5,6,6),(11,22,40,40),(11,20,40,44),(11,22,14,4),(1,2,3,3);

CREATE NONCLUSTERED INDEX indexA ON dbo.ATable(AColumn) INCLUDE(Set1);
CREATE NONCLUSTERED INDEX indexB ON dbo.ATable(BColumn) INCLUDE(Set2);

Теперь запустите следующее с включенным «Включить фактический план выполнения».

SELECT Set1 --Use Index A
FROM   dbo.ATable
WHERE  AColumn = 3
UNION ALL
SELECT Set2 --Use Index B
FROM   dbo.ATable
WHERE BColumn = 4;

... и план выполнения:

enter image description here

В запросе над UNION ALL выполняется некластеризация искать по ключевому столбцу IndexA (AColumn).Поскольку я включил Set1 в качестве столбца включения в IndexA, IndexA может удовлетворить запрос без поиска Rid или Key.Вот как должны быть разработаны индексы.То же самое относится и к запросу под UNION ALL, за исключением того, что он использует IndexB.

Опять же, это та вещь, которую легко понять самостоятельно, когда у вас есть полное понимание того, как читать планы выполнения.

0 голосов
/ 03 декабря 2018

Да, оптимизатор достаточно умен.Это две отдельные операции, которые могут выполняться либо как сканирование таблицы / индекса, либо как поиск.Решение для выполнения каждого из них является независимым, и совершенно нормально использовать разные индексы для каждого из них.Тогда результаты обеих операций будут объединены.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...