Давайте создадим простую таблицу tt
, подобную этой
WITH x AS (SELECT n FROM (VALUES (0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) v(n)), t1 AS
(
SELECT ones.n + 10 * tens.n + 100 * hundreds.n + 1000 * thousands.n + 10000 * tenthousands.n as id
FROM x ones, x tens, x hundreds, x thousands, x tenthousands, x hundredthousands
)
SELECT id,
id % 100 groupby,
row_number() over (partition by id % 100 order by id) orderby,
row_number() over (partition by id % 100 order by id) / (id % 100 + 1) local_search
INTO tt
FROM t1
У меня есть простой запрос Q1:
select distinct g1.groupby,
(select count(*) from tt g2
where local_search = 1 and g1.groupby = g2.groupby) as orderby
from tt g1
option(maxdop 1)
Я хотел бы знать, почему оценки SQL Serverразмер результата так плохо для Q1 (см. экран печати).Большинство операторов в плане запроса оцениваются точно, однако в корневом операторе Hash Match вводятся совершенно безумные догадки.
Чтобы сделать его более интересным, я пробовал различные переписывания Q1.Если я применяю декорреляцию подзапроса, я получаю эквивалентный запрос Q2:
select main.groupby,
coalesce(sub1.orderby,0) orderby
from
(
select distinct g1.groupby
from tt g1
) main
left join
(
select groupby, count(*) orderby
from tt g2
where local_search = 1
group by groupby
) sub1 on sub1.groupby = main.groupby
option(maxdop 1)
Этот запрос интересен в двух аспектах: (1) оценка является точной (см. Экран печати), (2) она также отличаетсяплан запроса, который более эффективен, чем план запроса Q1.
Итак, вопрос: почему оценка Q1 невернатогда как оценка Q2 является точной? Пожалуйста, не публикуйте другие переписывания этого SQL (я знаю, что это можно написать даже без подзапросов), меня интересует только объяснение поведения оценщика селективности.Спасибо.