Кардинальное число (мощность множества)
Пересказ статьи Bert Wagner. Cardinality: Not Just For The Birds
При построении индексов для ваших запросов порядок столбцов в ключе индекса имеет значение. SQL Server наиболее эффективно использует индекс, если данные в этом индексе сохраняются в том же порядке, какой требуется для вашего запроса при выполнении соединения (join), фильтрации (where), группировки (group by) или сортировки (order by).
Однако если ваш запрос требует нескольких ключевых столбцов из-за множества предикатов (например, WHERE Color = 'Red' AND Size = 'Medium'), какой порядок столбцов следует задать при определении ключевых столбцов в индексе?
В SQL Server кардинальное число (cardinality) означает число различных элементов в столбце. Оставив в стороне все другие соображения, скажем, что при определении ключевых столбцов для вашего индекса, столбец с наибольшим кардинальным числом, или с наибольшим числом различных значений, должен идти первым.
Чтобы понять почему так, давайте вернемся к нашему примеру с цветом и размером. Если у нас есть таблица с данными, представляющими цвета и размеры различных птиц, это может выглядеть примерно так:
Если подсчитать число различных значений в каждом из столбцов Color и Size, то обнаружим, что имеется 20 различных цветов, но только 5 различных размеров:
(Для простоты в этом примере данные в таблице распределены совершенно равномерно по всем 20 цветам и 5 размерам - т.е. каждый цвет представлен по одному каждым из пяти размеров, что в сумме дает 100 строк.)
Если мы поставим Size первым столбцом в индексном ключе, SQL Server мог бы сразу сократить число строк, среди которых он должен выполнить поиск, чтобы удовлетворить нашему предикату (WHERE Color = 'Red' and Size = 'Medium'), до 20 строк - после чего мы можем отсеять все строки, размер которых не равен Medium:
Однако если вместо этого мы сделаем Color первым столбцом, то можем сразу отбросить 95% строк в нашем наборе данных - оставив только 5 строк со значением 'Red', по одной строке на каждый из 5 размеров (помним, что данные распределены равномерно):
В большинстве сценариев размещение столбца с наивысшим кардинальным числом первым позволит SQL Server отфильтровать наибольшую часть данных, как неподходящих, сфокусировав внимание на меньшем подмножестве строк, которые еще требуется сравнить.
Хотя существуют обстоятельства, когда вы можете нарушить это общее правило, например, когда вы пытаетесь оптимизировать использование индекса под множество запросов; иногда может иметь смысл не помещать столбцы в порядке, определяемом максимальностью значений кардинального числа, если это приводит к тому, что большее количество запросов смогут использовать единственный индекс.
Кардинальное число
В SQL Server кардинальное число (cardinality) означает число различных элементов в столбце. Оставив в стороне все другие соображения, скажем, что при определении ключевых столбцов для вашего индекса, столбец с наибольшим кардинальным числом, или с наибольшим числом различных значений, должен идти первым.
Чтобы понять почему так, давайте вернемся к нашему примеру с цветом и размером. Если у нас есть таблица с данными, представляющими цвета и размеры различных птиц, это может выглядеть примерно так:
Если подсчитать число различных значений в каждом из столбцов Color и Size, то обнаружим, что имеется 20 различных цветов, но только 5 различных размеров:
SELECT
COUNT(DISTINCT Color) AS DistinctColors,
COUNT(DISTINCT Size) AS DistinctSizes
FROM
dbo.Birds
(Для простоты в этом примере данные в таблице распределены совершенно равномерно по всем 20 цветам и 5 размерам - т.е. каждый цвет представлен по одному каждым из пяти размеров, что в сумме дает 100 строк.)
Если мы поставим Size первым столбцом в индексном ключе, SQL Server мог бы сразу сократить число строк, среди которых он должен выполнить поиск, чтобы удовлетворить нашему предикату (WHERE Color = 'Red' and Size = 'Medium'), до 20 строк - после чего мы можем отсеять все строки, размер которых не равен Medium:
Однако если вместо этого мы сделаем Color первым столбцом, то можем сразу отбросить 95% строк в нашем наборе данных - оставив только 5 строк со значением 'Red', по одной строке на каждый из 5 размеров (помним, что данные распределены равномерно):
В большинстве сценариев размещение столбца с наивысшим кардинальным числом первым позволит SQL Server отфильтровать наибольшую часть данных, как неподходящих, сфокусировав внимание на меньшем подмножестве строк, которые еще требуется сравнить.
Хотя существуют обстоятельства, когда вы можете нарушить это общее правило, например, когда вы пытаетесь оптимизировать использование индекса под множество запросов; иногда может иметь смысл не помещать столбцы в порядке, определяемом максимальностью значений кардинального числа, если это приводит к тому, что большее количество запросов смогут использовать единственный индекс.
Обратные ссылки
Автор не разрешил комментировать эту запись
Комментарии
Показывать комментарии Как список | Древовидной структурой