Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности
|
|
|
Странная оценка количества строк
|
|||
|---|---|---|---|
|
#18+
Добрый день Исходные данные: Версия сервера: Microsoft SQL Server 2014 (KB4019093) - 12.0.5207.0 (X64) Есть две тестовые таблицы (для того чтобы показать поведение): Основная : Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. Содержит около 500 000 строк и вспомогательная: Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. Содержит около 430 000 строк При выполнении запроса Select TOP 1000 T0.OrderID,T7.OrderID from Main T0 LEFT JOIN Linked T7 ON T0.OrderID = T7.OrderId where T0.RegID Is Not Null AND T7.OrderID Is null order by T0.RegID План выполнения запроса в оценке строк показывает меньше записей чем их реальное количество. План прикрепил. Почему так? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.05.2018, 18:02 |
|
||
|
Странная оценка количества строк
|
|||
|---|---|---|---|
|
#18+
И второй Index Seek такая же картина ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.05.2018, 18:03 |
|
||
|
Странная оценка количества строк
|
|||
|---|---|---|---|
|
#18+
[сарказм]еще пару селектов сделайте, чтобы он статистику на таблицах обновил .[/сарказм] ну и OPTION ( RECOMPILE ) в конце, для красоты. Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.05.2018, 18:15 |
|
||
|
Странная оценка количества строк
|
|||
|---|---|---|---|
|
#18+
Руслан Дамирович, Таблицы только созданы, но для каждой из таблиц делал Update Statistics выполнил Ваш запрос,получилось все тоже самое. И еще вопрос - откуда оценочное число 7000 или 8000, 1000 строк запрашиваю. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.05.2018, 20:05 |
|
||
|
Странная оценка количества строк
|
|||
|---|---|---|---|
|
#18+
Алексей, Это оценочное количество строк не для всего запроса а для оператора index seek, сам же на скриншоте курсором оценку смотрите. Оптимизатор предполагает что у вас строк удовлетворяющих предикату поиска RegID is not null около 7000 update statistics как делаете? если она sampled то реальные данные могут в некоторой степени различаться от показателей распределения в гистограмме. покажите результат Код: sql 1. 2. и дополнительно для вашего запроса включите Код: sql 1. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.05.2018, 21:47 |
|
||
|
Странная оценка количества строк
|
|||
|---|---|---|---|
|
#18+
felix_ff, статистику делаю update statistics Main запрос возвращает две строки 1620200822;PK__Main__C3905BAF2A8B2BBF;1;0;0;0;0;NULL;0;0;1620200822;1;2018-05-14 17:41:01.3700000;497166;497166;11;497166;01620200822;IX_RegID;2;0;0;0;0;NULL;0;0;1620200822;2;2018-05-14 17:39:36.7670000;497166;497166;200;497166;0 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.05.2018, 23:18 |
|
||
|
Странная оценка количества строк
|
|||
|---|---|---|---|
|
#18+
felix_ff, при установленных флагах картина не поменялась ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.05.2018, 23:21 |
|
||
|
Странная оценка количества строк
|
|||
|---|---|---|---|
|
#18+
invm, спасибо ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.05.2018, 23:22 |
|
||
|
Странная оценка количества строк
|
|||
|---|---|---|---|
|
#18+
felix_ff, странно как то оценивает, если убрать Top 1000 (мне кажется, что причина кроется в нем) то оценка приблизительно правильная.... Warning появился..... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.05.2018, 07:22 |
|
||
|
Странная оценка количества строк
|
|||
|---|---|---|---|
|
#18+
Алексей, Вам invm не просто так ссылку скинул. Скорее всего дело в top, скорее всего используется row goal. В 2017 CU3 в плане показывается используется он или нет. Для того чтобы посчитать кол-во строк ему нужно знать селективность соеденеия и кол-во строк в таблице. Если интересно покапайтесь с включенными (НЕ ДОКУМЕНТИРОВАННЫМИ) флагами: 3604, 2363 Также можно использовать флаги 8607 и 8712, на выходе дерево физических оператор. Подробнее http://www.queryprocessor.ru/rowgoal-on-non-uniform-distribution/ ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.05.2018, 09:50 |
|
||
|
Странная оценка количества строк
|
|||
|---|---|---|---|
|
#18+
aleksrov, Спасибо огромное, буду разбираться ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.05.2018, 09:58 |
|
||
|
Странная оценка количества строк
|
|||
|---|---|---|---|
|
#18+
Алексей, в тему row goal покажите оценку Код: sql 1. 2. 3. 4. 5. 6. 7. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.05.2018, 10:58 |
|
||
|
Странная оценка количества строк
|
|||
|---|---|---|---|
|
#18+
Алексей, Немного дополню свой ответ простым примером. Предположим у нас есть таблица Table (id int, num int), статистика свежая, есть PK по id, по num ничего нет. В таблице 65552 строки, num равен id, т.е. по сути поле тоже уникально, на нем нет индекса, но есть статистика. Теперь я выполню: Код: sql 1. Вернулось 7 строк. План обычный - Select --> Top --> Clust. scan Смотрим на ожидание, если смотреть без флага 9130, то est. num of rows 7, чтобы увидеть нужной нам на плане, включает этот флаг, теперь фильтр у нас в плане "отдельно", теперь ожидание у нас 459.323 (Actual num of rows 7). Также можно посмотреть ожидание RowGoal с помощью 8607, 8612, как в ссылке выше. Теперь разбираемя откуда он взял 459.323. Включаем флаг 2363 и смотрим. Сначала посмотрим какую статистику он загрузил, там должна быть строчка : Loaded histogram for column : Table.num from stats with id = 2 (у меня, у вас может быть другое). Смотрим что это за статистика, можно через sys.stats с нашим object_id. Далее здесь смотри selectivity для нашего скана, она равна 0.0152398, в данном случае она считается 999\65552 (причем 6552 это данные с статистики) Также ниже можно увидеть кардинальность нашего фильтра, это будет 999: 0.0152398 * 65552 (а вот сейчас 65552 это уже метаданные нашей таблицы, т.е. если бы в к примеру у нас в таблице было 64500 строк, но в статистике было бы 65552, то эта цифра была бы 982.968: 0.0152398 * 64500. Кстати, если в таком случе убрать top, то это будет наш estimated number of rows у скана), но в случае с RowGoal, эти данные как я понимаю не используются (конкретно в моем примере). Я отвлекся, так откуда взялось 459.323, да все просто, зная селективность оптимизатор, учитывая равномерное распределение данные может оценить, сколько надо отсканить чтобы получить 7 строк : 7\0.0152398, если бы был top 6 то ожидаемое кол-во строк было бы 393.706 P.S. Не буду делать вида что полностью понимаю все кишки оптимизатора, на эту тему преступно мало статей, поэтому возможно где-то ошибся, скажу спасибо если меня поправят. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.05.2018, 11:20 |
|
||
|
Странная оценка количества строк
|
|||
|---|---|---|---|
|
#18+
aleksrov, так то всё это да, но ведь суть использования оценки кардинальности это в итоге выбор оптимального типа соединения, и как раз row goal корректирует и получаем NL вместо скорее всего HASH без корректировки ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.05.2018, 11:25 |
|
||
|
Странная оценка количества строк
|
|||
|---|---|---|---|
|
#18+
TaPaK, Я это понимаю, я имел ввиду что в данном случе, без соедения, когда from просто из одной таблицы и используется rowgoal то кардинальность считается, но не влияет на кол-во ожидаемых строк. А так да, кардинальность используется дальше, к прмиру я задавал Дмитрию вопрос, скопирую его сюда. I have one more question, it doesn't relate to this article, but it's about estimator. There is a query: SELECT * FROM [TSQL2012].[dbo].[Employees] as e join sales.Orders as o on e.ID = o.empid where (e.ID > 63000 and e.ID < 65000) or e.ID = 1 Employees has 63900 rows (in stat 65552), orders has 830 (in stat 830). At the top of the plan there's seek on Employess Clustered index, at the bottom scan on Orders. Selectivity of the seek is 0.0305101 and estimated number of rows 1949.6 Scan has selectivity of 1 and and estimated number of rows 830. Then there is merge join, it has selectvity 7.40964e-005 and estimated number of rows 119.9 I understand how it calculated 119.9 ( 7.40964e-005 * 1949.6 * 830), but i don't understand where he got 7.40964e-005. I have read your article http://www.queryprocessor.c... And it uses CselCalcExpressionComparedToExpression calculator, but in your article you didn't explain how exactly it calculate selectivity for this calculator. I hope you explain that. You write very interesting articles.Thanks again. Здесь видно что кардинальность использовалась в merge join для подсчета estimated number of rows. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.05.2018, 11:33 |
|
||
|
Странная оценка количества строк
|
|||
|---|---|---|---|
|
#18+
TaPaK, Как ее вывести? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.05.2018, 12:05 |
|
||
|
Странная оценка количества строк
|
|||
|---|---|---|---|
|
#18+
АлексейTaPaK, Как ее вывести? да всё то же Actual/Estimate rows ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.05.2018, 12:06 |
|
||
|
Странная оценка количества строк
|
|||
|---|---|---|---|
|
#18+
TaPaK, Для запроса Код: sql 1. 2. 3. 4. 5. 6. 7. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.05.2018, 12:26 |
|
||
|
Странная оценка количества строк
|
|||
|---|---|---|---|
|
#18+
С этим запросом количество ожидаемых строк увеличилось ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.05.2018, 12:28 |
|
||
|
Странная оценка количества строк
|
|||
|---|---|---|---|
|
#18+
Алексей, ну как я понимаю, в оригинале вы и видите скорректированную row goal оценку и на выходе NL, если хинт LOOP убрать и 4138 то получите скорее всего HASH. В оригинале оценка/факт меньше скорее из-за того, что на самом деле определить точно сколько же прийдется прочитать для получения вашей 1000 записией трудно/не возможно :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.05.2018, 12:35 |
|
||
|
|

start [/forum/topic.php?fid=46&msg=39644844&tid=1689721]: |
0ms |
get settings: |
7ms |
get forum list: |
14ms |
check forum access: |
2ms |
check topic access: |
2ms |
track hit: |
44ms |
get topic data: |
7ms |
get forum data: |
2ms |
get page messages: |
69ms |
get tp. blocked users: |
1ms |
| others: | 246ms |
| total: | 394ms |

| 0 / 0 |
