Оператор обновления занимает слишком много времени для выполнения - PullRequest
3 голосов
/ 02 сентября 2011

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

Значение по умолчанию для экспортируемого столбца: 0

UPDATE PAR_ITM SET exported = -1 WHERE exported < 1

Индексы:

CREATE NONCLUSTERED INDEX [IX_PAR_ITM_Exported_1]
ON [dbo].[PAR_ITM] ([exported] ASC)
WITH (
  PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = ON, SORT_IN_TEMPDB = OFF,
  IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON,
  ALLOW_PAGE_LOCKS  = ON, FILLFACTOR = 80
) ON [PRIMARY]

Ответы [ 5 ]

3 голосов
/ 02 сентября 2011

Количество элементов низкое
Вы страдаете из-за проблемы, которая называется low cardinality.
См. Википедия .

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

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

Почему - сюда вставлять БД - не использовать индекс?
Вот проблема.
Если более 50% (различается для каждой базы данных) всех строк вбаза данных имеет такое же значение, БД не будет использовать индекс, потому что было бы бессмысленно использовать индекс.

Бессмысленно делать 2 чтения для большинства строк (чтение 1 для индекса, чтение 2 для таблицы), если вы можете выполнить одно чтение (для самой таблицы).
БДв любом случае приходится читать большинство строк, поэтому он просто продолжает и читает их.
Тот факт, что БД вынуждена использовать свой самый медленный механизм доступа (полное сканирование таблицы), является причиной вашей медлительности.

Решение
Увеличить количество столбцов или увеличить количество элементов выбора.
В других работах убедитесь, что вы выбрали менее 50% всех строк, иубедитесь, что SQL-сервер знает (или может догадаться) об этом.

Как БД узнает мощность столбца?
Хорошая БД хранит статистику по таблицам и столбцам при выполнении операций выбора / обновления / вставки.Таким образом, он имеет информацию, необходимую для принятия обоснованных решений.

Ускорит ли использование индекса ускорение запроса?
Нет, это замедлит его.

SO ссылки
MySQL: столбцы с низкой кардинальностью / селективностью = как индексировать?
Индексация и альтернативы для столбцов с низкой селективностью

3 голосов
/ 02 сентября 2011

Итак, вы устанавливаете экспортируемое значение -1, где экспортируемое значение уже равно -1. Может быть, если вы измените предложение was на WHERE exported = 0, то попадет меньше строк?

1 голос
/ 02 сентября 2011

Вы также можете быть вовлечены в ситуацию блокировки с другим запросом.

1 голос
/ 02 сентября 2011

Я не думаю, что вам следует использовать некластеризованный индекс, так как кажется, что уникальности exported нет.Практическое правило для некластеризованных индексов - 95% уникальности, потому что оптимизатор запросов может не использовать индекс в противном случае, что означает, что вы замедляете его без причины.

Ознакомьтесь с этой статьейдля объяснения некластеризованного индекса:

http://www.sql -server-performance.com / 2007 / nonclustered-indexes /

1 голос
/ 02 сентября 2011

Может быть полезно узнать, сколько записей включено в это:

Select Count(*)
FROM PAR_ITM 
WHERE exported < 1

В основном, сколько строк обновляется.Конечно, даже миллион строк будет выполнен относительно быстро.

Медленно ли выполняются другие типы запросов на вашем сервере?

...