Построение, по общему признанию, достаточно простого тестового стенда на SQL Server 2012 (11.0.6020) позволяет мне воссоздать план с двумя запросами с хеш-соответствием, которые объединяются через UNION ALL
. Мой испытательный стенд не отображает неправильную оценку, которую вы видите. Возможно , это является проблемой SQL Server 2014 CE.
Я получил оценку 133,785 строк для запроса, который фактически возвращает 280 строк, однако этого следует ожидать, как мы увидим далее:
IF OBJECT_ID('dbo.Union1') IS NOT NULL
DROP TABLE dbo.Union1;
CREATE TABLE dbo.Union1
(
Union1_ID INT NOT NULL
CONSTRAINT PK_Union1
PRIMARY KEY CLUSTERED
IDENTITY(1,1)
, Union1_Text VARCHAR(255) NOT NULL
, Union1_ObjectID INT NOT NULL
);
IF OBJECT_ID('dbo.Union2') IS NOT NULL
DROP TABLE dbo.Union2;
CREATE TABLE dbo.Union2
(
Union2_ID INT NOT NULL
CONSTRAINT PK_Union2
PRIMARY KEY CLUSTERED
IDENTITY(2,2)
, Union2_Text VARCHAR(255) NOT NULL
, Union2_ObjectID INT NOT NULL
);
INSERT INTO dbo.Union1 (Union1_Text, Union1_ObjectID)
SELECT o.name, o.object_id
FROM sys.objects o;
INSERT INTO dbo.Union2 (Union2_Text, Union2_ObjectID)
SELECT o.name, o.object_id
FROM sys.objects o;
GO
SELECT *
FROM dbo.Union1 u1
INNER HASH JOIN sys.objects o ON u1.Union1_ObjectID = o.object_id
UNION ALL
SELECT *
FROM dbo.Union2 u2
INNER HASH JOIN sys.objects o ON u2.Union2_ObjectID = o.object_id;
Я думаю, что причина заключается в отсутствии статистики для двух объединений, которые в результате UNIONed. SQL Server в большинстве случаев необходимо делать обоснованные предположения относительно избирательности столбцов в случае отсутствия статистики.
У Джо Сака есть интересное прочтение об этом здесь .
Для a UNION ALL
можно с уверенностью сказать, что мы увидим точно общее количество строк, возвращаемых каждым компонентом объединения, однако, поскольку SQL Server использует оценки строк для двух компонентов UNION ALL
, мы видим, что он добавляет итоговые оценочные строки из обоих запросы для получения оценки для оператора конкатенации.
В моем примере выше предполагаемое количество строк для каждой части UNION ALL
составляет 66,8927, что при суммировании равно 133,785, что мы видим для примерного количества строк для оператора конкатенации.
Фактический план выполнения для запроса объединения выглядит следующим образом:
Вы можете увидеть «примерное» и «фактическое» количество строк. В моем случае добавление «оценочного» числа строк, возвращаемых двумя операторами совпадения хешей, в точности равно количеству, показанному оператором конкатенации.
Я бы попытался получить вывод из трассы 2363 и т. Д., Как рекомендовано в посте Пола Уайта, который вы показываете в своем вопросе. С другой стороны, вы можете попытаться использовать OPTION (QUERYTRACEON 9481)
в запросе, чтобы вернуться к версии 70 CE, чтобы увидеть, устраняет ли это проблему.