Перевод статьи: Kendra Little
Я никогда не была хороша в математике, но до этого момент я считала, что смогу посчитать до 1…
0…1…Я это выучила ещё в детском саду.
По всей видимости SQL Server не ходил в детский сад
Он даже не может в плане выполнения (execution plan) посчитать до 1.
У меня есть очень простой запрос, который выполняется на таблице с некластерным колоночным индексом.
SELECT COUNT(*) FROM pt.FirstNameByBirthDate_1966_2015; GO
Запрос возвращает 1 строку, как и ожидалось:
Но план запроса показывает странную картину, колоночный индекс возвращает 0 строк.
Да, это настоящий актуальный план, я не шучу, честно.
0 строк входит в оператор hash match, но 1 строка выходит
Словно строка появляется из ниоткуда
Наш оператор hash match — это физический оператор.
Посмотрим на свойства оператора сканирования колоночного индекса
Опять что-то странное
Сканирование колоночного индекса выполняется в пакетной обработке (batch mode) и использует 4 ядра. Каждый поток выполняется сканирование, но каким-то образом не выполняет ни 1 чтения. Как же так?
На самом деле работа выполняется, посмотрите на locally aggregated rows.
Это оптимизация batch mode колоночного индекса в Enterprise Edition
Locally aggregated rows называется aggregate pushdown. Это одно из улучшений SQL Server 2016, которое доступно только в Enterprise Edition и делает ваши колоночные индексы быстрее.
Но это выглядит неправильным!
Я согласна, это выглядит неправильным, поэтому я спросила Niko об этом. Когда я думал о колоночным индексах, я всегда вспоминаю его.
Я спросила его: «Это баг или фича?».
Niko объяснил что это фича или по крайней мере это было сделано специально. На самом деле план выполнения пытается сказать нам что-то вроде:
План выполнения пытается объяснить что hash match не выполняет каких либо подсчётов, потому что колоночный индекс делает это каким-то магическим образом
Но…Но…это всё равно выглядит неправильно
SQL Server пьян, по крайней мере это то, что я сказала Niko и по его взгляду я поняла, что он согласен со мной. Он не подтвердил что это баг в плане выполнения, это было сделано специально.