Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Ошибка определения кардинальности при объединении таблиц  [new]
VertNumberOne
Member

Откуда: Санкт-Петербург
Сообщений: 5
Столкнулся с проблемой, в поисках решения которой уже сломал голову и замучил гугл.

Допустим, у нас есть 2 таблицы:
1) clients (subid int PK, card_num int, class_num int FK)
2) classes (class_num int PK, classid int UQ)

В первой таблице у нас десятки миллионов строк. Во второй - просто пара десятков. Для таблицы clients есть покрывающий индекс по столбцу class_num (include card_num, subid), есть свежая актуальная статистика (распределение количества записей по card_num ни разу не равномерное - для каких-то значение миллионы, для других единицы).

Мы пытаемся получить данные довольно простым запросом:
select cli.subid, cli.card_num, cla.classid from clients cli
inner join classes cla on cla.class_num = cli.class_num
where cli.classid = 1


В плане выполнения видим непонятную мне мистику. Планировщик, при определении кардинальности извлекаемых их clients строк, берет среднее значение, которое меньше реально извлекаемого на порядок (примерно 1кк против 10кк). Отсюда следует неправильная оценка общей стоимости плана выполнения и spill промежутощных данных в temp_db, которого очень бы хотелось избежать.

Я пробовал перестраивать индексы, добавлять фильтрующую статистику - не помогает. Использование хинтов для джоинов тоже не дает положительных результатов. Option (recompile) - не спасает.

Причина по большей части кроется в условии
where cli.classid = 1
- в плане выполнения планировщик вместо конкретного значение подставляет Scalar Operator([classes].[class_num] as [cla].[class_num]).
Пока склоняюсь к тому, что в SQL Serverv 2012 SP1 есть баг с определением кардинальности в определнных условиях, но не хочу в это верить. :)

Кто-нибудь сталкивался с такой проблемой? Как это победить?
6 июн 17, 11:36    [20542682]     Ответить | Цитировать Сообщить модератору
 Re: Ошибка определения кардинальности при объединении таблиц  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6794
VertNumberOne,

дайте план файлом, зачем пересказ
6 июн 17, 11:40    [20542707]     Ответить | Цитировать Сообщить модератору
 Re: Ошибка определения кардинальности при объединении таблиц  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6794
VertNumberOne,
ну и
автор
Scalar Operator([classes].[class_num] as [cla].[class_num]).

а что тут по вашему должно быть
6 июн 17, 11:42    [20542717]     Ответить | Цитировать Сообщить модератору
 Re: Ошибка определения кардинальности при объединении таблиц  [new]
VertNumberOne
Member

Откуда: Санкт-Петербург
Сообщений: 5
TaPaK,

тут все верно, по всей видимости. Но хочется, чтобы скуль как-то допер, что ему придется вынуть не меньше 10 миллионов строк. Точно знаю, что если бы там было конкретное значение, то и проблем бы не было (но если бы тут не работает, к сожалению). Дальше хуже - наши программеры хотят вытаскивать данные по условию where cli.classid in (...). :)
План выполнения с коммерческого продукта компании выложить на форум не могу. А времени запилить фейковую базу для исследования проблемы пока нет.
6 июн 17, 11:51    [20542756]     Ответить | Цитировать Сообщить модератору
 Re: Ошибка определения кардинальности при объединении таблиц  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6794
VertNumberOne,

 classes (class_num int PK, classid int UQ)

а почему кластерный не class_num,classid раз там всё уникально
6 июн 17, 12:06    [20542802]     Ответить | Цитировать Сообщить модератору
 Re: Ошибка определения кардинальности при объединении таблиц  [new]
VertNumberOne
Member

Откуда: Санкт-Петербург
Сообщений: 5
TaPaK,

так требует бизнес логика.
В любом случае, создание дополнительного индекса по полю никак не помогает решить проблему. Пробовал.
6 июн 17, 15:49    [20543819]     Ответить | Цитировать Сообщить модератору
 Re: Ошибка определения кардинальности при объединении таблиц  [new]
aleks2
Guest
VertNumberOne
1) clients (subid int PK, card_num int, class_num int FK)
2) classes (class_num int PK, classid int UQ)

select cli.subid, cli.card_num, cla.classid from clients cli
inner join classes cla on cla.class_num = cli.class_num
where cli.classid = 1




Я один не вижу в определении таблицы
clients cli

cli.classid 

?

ЗЫ. Тредстартер несет чушь.
6 июн 17, 16:31    [20544036]     Ответить | Цитировать Сообщить модератору
 Re: Ошибка определения кардинальности при объединении таблиц  [new]
VertNumberOne
Member

Откуда: Санкт-Петербург
Сообщений: 5
aleks2,

Там опечатка, должно быть where cla.classid = 1.
Спасибо, что указали на ошибку. Больше в данной теме можете не писать.
6 июн 17, 18:04    [20544442]     Ответить | Цитировать Сообщить модератору
 Re: Ошибка определения кардинальности при объединении таблиц  [new]
o-o
Guest
какое-нибудь parameterization forced на базе?
6 июн 17, 18:23    [20544495]     Ответить | Цитировать Сообщить модератору
 Re: Ошибка определения кардинальности при объединении таблиц  [new]
aleks2
Guest
VertNumberOne
aleks2,

Там опечатка, должно быть where cla.classid = 1.
Спасибо, что указали на ошибку. Больше в данной теме можете не писать.


У тя ж весь запрос - одна большая ошибка.

Сообщение было отредактировано: 6 июн 17, 20:37
6 июн 17, 18:45    [20544549]     Ответить | Цитировать Сообщить модератору
 Re: Ошибка определения кардинальности при объединении таблиц  [new]
VertNumberOne
Member

Откуда: Санкт-Петербург
Сообщений: 5
o-o,

Ничего такого, PARAMETERIZATION FORCED не включал.
6 июн 17, 18:59    [20544579]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить