Производительность SQL Server 2008: нет индексов против плохих индексов? - PullRequest
1 голос
/ 03 июня 2009

У меня странная проблема в Microsoft SQL Server 2008. У меня есть большая база данных (20 ГБ) с 10 таблицами, и я пытаюсь показать, как правильно создавать индексы.

Вот моя проблема: по некоторым вложенным запросам я получаю более быстрые результаты без с использованием индексов! Это близко (одна или две секунды), но в некоторых случаях использование вообще никаких индексов, кажется, заставляет эти запросы работать быстрее ... Я запускаю Checkpoiunt и DBCC dropcleanbuffers для сброса кэшей перед запуском сценариев, поэтому я ' м вроде как потерялся.

Что может быть причиной этого? Я точно знаю, что индексы плохо построены (подумайте, по одному индексу на релевантное поле), весь смысл в том, чтобы доказать важность их правильного построения, но это не должно быть медленнее, чем отсутствие индексов в все, верно?

РЕДАКТИРОВАТЬ: вот один из виновных запросов:

SET STATISTICS TIME ON
SET STATISTICS IO ON

USE DBX;
GO
CHECKPOINT;
GO
DBCC DROPCLEANBUFFERS;
GO
DBCC FREEPROCCACHE;
GO

SELECT * FROM Identifier where CarId in (SELECT CarID from Car where ManufactId = 14) and DataTypeId = 1

Таблица идентификаторов: - IdentifierId int не нуль - CarId int not null - DataTypeId int не равен NULL - Alias ​​nvarchar (300)

Автомобильный стол: - CarId int not null - ManufactId int не нуль - (после нескольких полей, все nvarchar (100)

Каждая из этих маркированных точек имеет индекс вместе с некоторыми индексами, которые одновременно хранят две из них одновременно (например, CarId и DataTypeId).

Наконец, таблица идентификаторов содержит более миллиона записей, а таблица Car - два или три миллиона

Ответы [ 11 ]

4 голосов
/ 03 июня 2009

Я полагаю, что SQL Server неправильно решает использовать индекс, который затем вызывает поиск закладок *. Обычно, когда это происходит (неправильное использование индекса), это потому, что статистика в таблице неверна.

Это может особенно случиться, если вы только что загрузили большие объемы данных в одну или несколько таблиц. Или, может быть, SQL Server просто облажался. Такое случается довольно редко (с одной стороны, я могу сосчитать, сколько раз мне приходилось форсировать использование индексов за 15 лет работы с SQL Server), но оптимизатор не идеален.

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

Один из способов избавиться от поиска по закладкам - это использовать покрывающие индексы - индекс, в котором сначала есть столбцы фильтрации, но затем также включаются любые другие столбцы, которые вам понадобятся в «покрытом» запросе. Например:

SELECT
     my_string1,
     my_string2
FROM
     My_Table
WHERE
     my_date > '2000-01-01'

индекс покрытия будет (my_date, my_string1, my_string2)

1 голос
/ 03 июня 2009

Для некоторых запросов быстрее читать непосредственно из таблицы (сканирование кластерного индекса), чем читать индекс и извлекать записи из таблицы (сканирование индекса + поиск по закладкам).

Учтите, что запись живет вместе с другими записями в странице данных. Datapage является основной единицей ввода-вывода. Если таблица читается напрямую, вы можете получить 10 записей по цене 1 IO. Если индекс читается напрямую, а затем записи извлекаются из таблицы, вы должны заплатить 1 IO за запись.

Как правило, SQL-сервер очень хорошо выбирает лучший способ доступа к таблице (прямой по сравнению с индексом). В вашем запросе может быть что-то, что ослепляет оптимизатор. Советы по запросу могут дать указание оптимизатору использовать индекс, если это неправильно. Советы по соединению могут изменить порядок или метод доступа к таблице. Считается, что переменные таблицы имеют 0 записей оптимизатором, поэтому, если у вас большая переменная таблицы, оптимизатор может выбрать неверный план.

Еще одна вещь, на которую стоит обратить внимание - varchar vs nvarchar. Убедитесь, что все параметры одного типа с целевыми столбцами. Существует случай, когда SQL Server преобразует весь индекс в тип параметра в случае несоответствия типов.

1 голос
/ 03 июня 2009

Это пустое предположение. Возможно, если у вас много индексов, SQL Server тратит время на их анализ и выбор, а затем отвергает все из них. Если бы у вас не было индексов, двигателю не пришлось бы тратить время на проверку.

Сколько времени на самом деле занимает этот процесс проверки, я понятия не имею.

1 голос
/ 03 июня 2009

Попробуйте DBCC FREEPROCCACHE , чтобы также очистить кэш плана выполнения.

1 голос
/ 03 июня 2009

Индексы на самом деле не имеют никакой пользы, пока у вас не будет много записей. Я говорю много, потому что я действительно не знаю, что это за переломный момент ... Это зависит от конкретного применения и обстоятельств.

SQL Server требуется время для работы с индексом. Если это время превышает выгоду ... Это особенно верно для подзапросов, где будет умножаться небольшая разница.

Если это работает лучше без индекса, пропустите индекс.

1 голос
/ 03 июня 2009

Обычно SQL Server хорошо решает, какой индекс использовать, если он есть, для получения данных самым быстрым способом. Довольно часто он решает не использовать какие-либо индексы, поскольку может быстрее извлекать небольшие объемы данных из небольших таблиц, не переходя к индексу (в некоторых ситуациях).

Похоже, в вашем случае SQL может идти не самым оптимальным путем. Наличие большого количества плохо созданных индексов может привести к тому, что он выберет неправильные маршруты для доступа к данным.

Я бы предложил посмотреть план запросов в Management Studio, чтобы проверить, какие индексы он использует и где берется время. Это должно дать вам хорошее представление, с чего начать.

Еще одно замечание: возможно, эти индексы со временем стали фрагментированными и теперь не работают лучше, возможно, стоит проверить это и перестроить некоторые из них, если это необходимо.

0 голосов
/ 03 июня 2009

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

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

дайте нам образец запросов, которые вы используете.

хорошо ...

попробуйте это и посмотрите, получите ли вы какой-либо прирост производительности (с индексами pk)

SELECT i.* 
FROM Identifier i 
    inner join Car c
        on i.CarID=c.CarID
where c.ManufactId = 14 and i.DataTypeId = 1
0 голосов
/ 03 июня 2009

Нет. Sql Server анализирует индексы и статистику, прежде чем принять решение об использовании индекса для ускорения запроса. Вполне возможно, что запуск неиндексированной версии происходит быстрее, чем индексированной версии.

Несколько вещей, которые стоит попробовать

  1. убедиться, что индексы созданы, перестроены и реорганизованы (дефрагментированы).

  2. убедитесь, что автоматическое создание статистики включено.

  3. Попробуйте использовать Sql Profiler для захвата профиля настройки, а затем с помощью помощника по настройке ядра СУБД создать свои индексы.

Удивительно, но книга MS Press Examination для администрирования Sql довольно хорошо объясняет индексы и статистику.

См. Оглавление главы 4 в этом превью книги для амазонок читателя

Amazon Reader из Sql 2008 MCTS Exam Book

0 голосов
/ 03 июня 2009

пробег:

SET SHOWPLAN_ALL ON

, а затем запустите запрос с использованием индекса и без него, это позволит вам увидеть, какой индекс используется, где идет работа, и т. Д.

0 голосов
/ 03 июня 2009

SQL-сервер фактически создает некоторые индексы для вас (например, по первичному ключу).

Индексы могут стать фрагментированными.

Слишком большое количество индексов всегда снижает производительность (есть часто задаваемые вопросы о том, почему не индексировать каждый столбец в БД)

также существуют ситуации, когда индексы всегда будут медленнее .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...