11 секунд, чтобы удалить 240 строк в SQL Server - PullRequest
7 голосов
/ 05 октября 2011

я выполняю оператор удаления:

DELETE FROM TransactionEntries
WHERE SessionGUID = @SessionGUID

Фактический план выполнения удаления:

Execution Tree
--------------
Clustered Index Delete(
   OBJECT:([GrobManagementSystemLive].[dbo].[TransactionEntries].IX_TransactionEntries_SessionGUIDTransactionGUID]), 
   WHERE:([TransactionEntries].[SessionGUID]=[@SessionGUID])
)

Таблица сгруппирована по SessionGUID, поэтому 240 строк физически вместе.

В таблице нет триггеров.

Операция занимает:

  • Продолжительность: 11821 мс
  • ЦП: 297
  • Читает: 14340
  • Пишет: 1707

Таблица содержит 11 индексов:

  • 1 кластерный индекс (SessionGUID)
  • 1 уникальный (первичный ключ) индекс
  • 9 других неуникальных некластеризованных индексов

Как я могу выяснить, почему эта delete операция выполняет 14,340 операций чтения и занимает 11 секунд?

  • Avg. Disk Read Queue Length достигает 0.8
  • Avg. Disk sec/Read никогда не превышает 4ms
  • Avg. Disk Write Queue Length достигает 0.04
  • Avg. Disk sec/Write никогда не превышает 4ms

Для чего другие чтения? В плане выполнения не указывается что читает.


Обновление

EXECUTE sp_spaceused TransactionEntries

TransactionEntries  
  Rows      6,696,199
  Data:     1,626,496 KB (249 bytes per row)
  Indexes:  7,303,848 KB (1117 bytes per row)
  Unused:      91,648 KB    
            ============
  Reserved: 9,021,992 KB (1380 bytes per row)

С 1,380 байтами на строку и 240 строками, это 340 kB для удаления.

Счетчик интуитивно понятен, что это может быть настолько сложно для 340 кБ.

Обновление два : фрагментация

Name                           Scan Density  Logical Fragmentation
=============================  ============  =====================
IX_TransactionEntries_Tran...  12.834        48.392
IX_TransactionEntries_Curr...  15.419        41.239
IX_TransactionEntries_Tran...  12.875        48.372
TransactionEntries17           98.081         0.0049325
TransactionEntries5            12.960        48.180
PK_TransactionEntries          12.869        48.376
TransactionEntries18           12.886        48.480
IX_TranasctionEntries_CDR...   12.799        49.157
IX_TransactionEntries_CDR...   12.969        48.103
IX_TransactionEntries_Tra...   13.181        47.127

я дефрагментировал TransactionEntries17

DBCC INDEXDEFRAG (0, 'TransactionEntries', 'TransactionEntries17')

, поскольку INDEXDEFRAG является « оперативной операцией » (т. Е. Она содержит только IS Intent Shared lock). Затем я собирался вручную дефрагментировать остальные, пока не были вызваны бизнес-операции, в которых говорилось, что система мертва - и они переключились на выполнение всего на бумаге.

Что скажете вы; 50% фрагментации и только 12% плотности сканирования вызывают ужасную производительность сканирования индекса?

Ответы [ 3 ]

5 голосов
/ 05 октября 2011

Как отмечает @JoeStefanelli в комментариях, это дополнительные некластеризованные индексы.

Вы удаляете 240 строк из таблицы.

Это равняется 2640 индексным строкам, 240 из которых включают все поля в таблице.

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

Некластеризованные строки индекса определенно будут НЕ сгруппированы на диске, что увеличит задержки.

1 голос
/ 05 октября 2011

Я думаю, что индексация может быть наиболее вероятным виновником, но я хотел исключить другую возможность. Вы не упомянули триггеры, но есть ли таблицы, имеющие отношение внешнего ключа к этой таблице? Их нужно будет проверить, чтобы убедиться, что в них нет записей, и если у вас включено каскадное удаление, эти записи также должны быть удалены.

1 голос
/ 05 октября 2011

Ударяя головой о проблеме производительности многих SQL, моя стандартная рабочая процедура для чего-то вроде этого:

  1. Резервное копирование данных
  2. Удаление одного изиндексы в рассматриваемой таблице
  3. Измерьте операцию
  4. Восстановите БД
  5. Повторяйте w / # 2 до тех пор, пока # 3 не покажет резкое изменение.Это, вероятно, ваш виновник.
...