При какой мощности SQL Server переключается на сканирование индекса (вместо поиска)

Если предположить, что таблица содержит достаточно информации, чтобы гарантировать поиск по индексу, с какой мощностью SQL Server (или PostgreSQL) выберет сканирование индекса?

Причина, по которой я спрашиваю об этом, заключается в том, что я ранее разместил вопрос (link), в котором два запроса выполнялись с одинаковой скоростью, но ни один из них не пытался использовать индекс для обработанных столбцов. После того, как SQL Server предложил мне поместить покрывающий индекс, который включал запрашиваемые столбцы (он предлагал это для обоих запросов), я начал искать причины, по которым это странное предложение.

Я экспериментировал с индексами, покрывающими и составными, но оба выполнялись одновременно (мы говорим о 3 миллионах строк).

В конце концов я пришел к выводу, что это произошло из-за сверхвысокой мощности данных. Каждая строка уникальна. Я предполагаю, что это заставило SQL-сервер выбрать сканирование индекса. Однако в запросе указано «ГДЕ Col1>? AND Col2‹? », Так что это немного сбивает с толку.

Мои вопросы:

  1. При какой мощности РСУБД всегда выбирает сканирование индекса?
  2. Может ли кто-нибудь объяснить, почему SQL Server не использует индекс, если оператор WHERE указывает, что это имеет смысл?

Я приложил план исполнения. alt text


person IamIC    schedule 02.01.2011    source источник


Ответы (2)


С точки зрения SQL Server это было названо переломным моментом, и сообщение в блоге Кимберли - хорошее прочтение. http://www.sqlskills.com/BLOGS/KIMBERLY/category/The-Tipping-Point.aspx

Переломный момент - это ориентировочное значение 25% -33% от общего количества страниц в таблице, выраженное в виде строк, например 10 тыс. Страниц данных дадут переломный момент в 2500-3333 строк. В соответствии с руководящими принципами это довольно хорошо, и насколько вы получите - помните, что механизм плана запроса - это черный ящик, и хотя он дает вам план запроса, он только говорит, что он решил, а не почему.

Однако с точки зрения изменения индекса покрытия это на самом деле не очень просто, даже если выбрано 100% данных, индекс покрытия в большинстве случаев все равно будет искать через сканирование.

Это имеет смысл, если учесть, что оптимизатор затрат не назначает никакой реальной стоимости иерархии страниц индекса, а только затраты на доступ к конечным страницам индекса. В этот момент сканирование или поиск 100% индекса покрытия оплачивается одинаково.

В ходе собственных экспериментов я обнаружил (http://sqlfascination.com/2009/11/07/can-a-covering-nc-index-be-tipped) с использованием предложения between приведет к сканированию, но другие предложения where не будут - из того, что я мог сказать, это было связано исключительно с маршрутом через механизм запросов.

person Andrew    schedule 02.01.2011
comment
Отличный ответ @Andrew. Это хорошо проясняет ситуацию и объясняет, почему SQL Server решил сканировать индекс. - person IamIC; 02.01.2011
comment
@Andrew: Что касается индекса покрытия, это на самом деле не очень просто, даже если выбрано 100% данных, индекс покрытия в большинстве случаев все равно будет искать через сканирование - почему это? - person IamIC; 02.01.2011
comment
Механизм планирования запросов - это оптимизатор на основе затрат, учитывая, что доступ к иерархии индекса оценивается как 0, поиск каждой конечной страницы в индексе - это те же затраты, что и сканирование каждой конечной страницы в индексе (с точки зрения затрат). В зависимости от используемого предложения where я видел, что он выполняет и то, и другое, но потребовались значительные усилия, чтобы заставить его сканировать, по умолчанию был поиск - person Andrew; 02.01.2011
comment
@ Андрей Ок. Как узнать, когда лучше всего использовать построенный покрывающий индекс: join_column include (столбцы сравнения 1 - n) или составной индекс, созданный: (join_column, столбцы сравнения 1 - n), учитывая, что последний склонен к опрокидыванию, но имеет ли преимущество компонентов индекса в столбцах сравнения? - person IamIC; 02.01.2011
comment
Если бы я знал, что использую столбец в некоторых критериях запроса, я бы поместил его в индексированный раздел, а не в раздел включения. Но на самом деле, если индекс покрывает, то вряд ли он даст опрокидывание, мне показалось, что для меня это подействует только предложение между стилями, при выборе 100%, в остальное время, индекс покрытия не опрокинется. - person Andrew; 02.01.2011
comment
Спасибо. Я думаю, единственный способ действительно увидеть, что будет оптимальным, - это протестировать оба с реальными данными. Очевидно, что за чаевые приходится платить, как и за неиспользование индекса для сравниваемого поля. Я в середине вашей статьи ... вы упоминаете МЕЖДУ, вызывая чаевые. А как насчет IN ()? - person IamIC; 02.01.2011
comment
По памяти не опрокинул, предложение In преобразуется в набор предложений OR - person Andrew; 02.01.2011
comment
Таким образом, все, что приравнивается к равенству, похоже, предотвращает опрокидывание, а все, что связано с диапазонами (›,‹, между), кажется, допускает опрокидывание. Это похоже на точное суммирование? - person IamIC; 02.01.2011
comment
если диапазон в конечном итоге составляет 100% данных, да, в этот момент поиск и сканирование были довольно несущественными. Если бы я использовал промежуточное звено для меньшего количества данных, это не помогло бы. - person Andrew; 02.01.2011

В PostgreSQL это обычно не лучший вопрос, потому что фактический выбор плана более сложен. Это зависит от размера таблицы, настроек памяти и других частей запроса. Обычно вы получаете простой просмотр индекса только в том случае, если вы выбираете очень мало строк. Кроме того, в простых экспериментах вы получите сканирование индекса растрового изображения с селективностью, скажем, до 40%.

person Peter Eisentraut    schedule 02.01.2011
comment
Спасибо @Peter. Вы упоминаете индексы Bitmap (потомок M / Caché). В каких условиях они используются? (я предполагаю, что низкая мощность) - person IamIC; 02.01.2011
comment
Пс. Я новичок в PostgreSQL, но имею опыт работы с SQL Server. - person IamIC; 02.01.2011
comment
При сканировании растрового индекса не используется растровый индекс (которого нет в PostgreSQL). Это своего рода сканирование индекса, при котором по ходу работы используются некоторые растровые изображения. Как я уже писал выше, они используются где-то между обычным сканированием индекса и последовательным сканированием. - person Peter Eisentraut; 02.01.2011