SQL Server: поиск или сканирование. Если столбец неуникальный и относится к целому или числовому типу, начиная с 0
Содержание:
1. Проблема возрастающего ключа;
2.Если столбец неуникальный и относится к целому или числовому типу, начиная с 0 (Вы читаете данный раздел);
3. Если столбец уникален и не относится к целому или числовому типу, начиная с 0.
Как говорилось выше, уникальность столбца и его тип могут влиять на метод оценки числа элементов, применяемый SQL Server. Ниже описаны методы, применяемые SQL Server, если уникальность столбца не обеспечивается и столбец относится к целому и числовому типу, начиная с 0. Выполним приведенный в листинге 4 код для повторного создания демонстрационных данных, но на этот раз с неуникальным индексом.
В обоих случаях, для которых данный код строит гистограмму, получается результат, аналогичный представленному в таблице выше.
В приведенном ниже запросе применяется фильтр, не пересекающийся с максимальным значением на гистограмме, и предусмотрено использование более старой версии СЕ:
Как и в случае с уникальным индексом, получается сильно заниженная оценка числа элементов, равная 1.
Новая версия СЕ делает нечто удивительное и отличное от того, что бывает в случае с уникальным индексом. По всей вероятности, исходное предположение, что столбец является возрастающим, не делается. Поэтому к счетчику modctr применяется жестко заданное значение в процентах, зависящее от используемого оператора. Эти значения в процентах используются в оценках для предикатов с неизвестным входом. Например, для оператора > применяется 30%, а для оператора BETWEEN — 9%. В нашем случае значение modctr — 100000. Поэтому для запроса с предикатом orderid > 900000 оценка рассчитывается как 0,30 х 100000 = 30000. Запрос приведен ниже:
План запроса показан на скриншоте выше в подтверждение того, что использовался этот метод оценки числа элементов.
Если столбец — возрастающий, то весьма вероятно получение заниженной оценки; однако результат все же будет выше, чем тот, что получается с СЕ более старой версии. Если столбец невозрастающий, то оценка, скорее всего, получится более точной.
Удивительно, что если предикат фильтра пересекается с максимальным значением на гистограмме, то оба варианта СЕ (более старая и более новая версии) применяют оценку, основанную на существующей гистограмме, и пересчитывают ее с учетом значения счетчика modctr. Удивительно это потому, что при использовании СЕ новой версии, как мы только что видели, для фильтра предиката orderid > 900000 получается оценка, равная 30000, тогда как для orderid >= 900000 получается 1,11111! Оценка вычисляется как 1 + (100000/900000). В этом можно убедиться на примере следующего запроса:
План запроса показан на скриншоте выше.
В дополнение к тому, что разные версии СЕ используют разные методы, здесь мы также видим пример ситуации, когда одна и та же версия СЕ с одними и теми же входными данными дает для предиката с оператором >= в качестве оценки меньшее число, чем для предиката с оператором >.
1. Проблема возрастающего ключа;
2.
3. Если столбец уникален и не относится к целому или числовому типу, начиная с 0.
Как говорилось выше, уникальность столбца и его тип могут влиять на метод оценки числа элементов, применяемый SQL Server. Ниже описаны методы, применяемые SQL Server, если уникальность столбца не обеспечивается и столбец относится к целому и числовому типу, начиная с 0. Выполним приведенный в листинге 4 код для повторного создания демонстрационных данных, но на этот раз с неуникальным индексом.
В обоих случаях, для которых данный код строит гистограмму, получается результат, аналогичный представленному в таблице выше.
В приведенном ниже запросе применяется фильтр, не пересекающийся с максимальным значением на гистограмме, и предусмотрено использование более старой версии СЕ:
SELECT empid, COUNT (*) AS numorders
FROM dbo.Orders2
WHERE orderid > 900000
GROUP BY empid
OPTION (QUERYTRACEON 9481);Как и в случае с уникальным индексом, получается сильно заниженная оценка числа элементов, равная 1.
Новая версия СЕ делает нечто удивительное и отличное от того, что бывает в случае с уникальным индексом. По всей вероятности, исходное предположение, что столбец является возрастающим, не делается. Поэтому к счетчику modctr применяется жестко заданное значение в процентах, зависящее от используемого оператора. Эти значения в процентах используются в оценках для предикатов с неизвестным входом. Например, для оператора > применяется 30%, а для оператора BETWEEN — 9%. В нашем случае значение modctr — 100000. Поэтому для запроса с предикатом orderid > 900000 оценка рассчитывается как 0,30 х 100000 = 30000. Запрос приведен ниже:
SELECT empid, COUNT (*) AS numorders
FROM dbo.Orders2
WHERE orderid >900000
GROUP BY empid;План запроса показан на скриншоте выше в подтверждение того, что использовался этот метод оценки числа элементов.
Если столбец — возрастающий, то весьма вероятно получение заниженной оценки; однако результат все же будет выше, чем тот, что получается с СЕ более старой версии. Если столбец невозрастающий, то оценка, скорее всего, получится более точной.
Удивительно, что если предикат фильтра пересекается с максимальным значением на гистограмме, то оба варианта СЕ (более старая и более новая версии) применяют оценку, основанную на существующей гистограмме, и пересчитывают ее с учетом значения счетчика modctr. Удивительно это потому, что при использовании СЕ новой версии, как мы только что видели, для фильтра предиката orderid > 900000 получается оценка, равная 30000, тогда как для orderid >= 900000 получается 1,11111! Оценка вычисляется как 1 + (100000/900000). В этом можно убедиться на примере следующего запроса:
SELECT empid, COUNT (*) AS numorders
FROM dbo.Orders2
WHERE orderid >-900000
GROUP BY empid;План запроса показан на скриншоте выше.
В дополнение к тому, что разные версии СЕ используют разные методы, здесь мы также видим пример ситуации, когда одна и та же версия СЕ с одними и теми же входными данными дает для предиката с оператором >= в качестве оценки меньшее число, чем для предиката с оператором >.