Медленный MSSQL на БД (~2 ТБ) - индекс / фрагментация?
У меня довольно большая база данных MS SQL (~2 ТБ). Большая часть данных находится в одной таблице (~6 миллиардов строк).
Две недели назад я отбросил два некластеризованных индекса в большой таблице и перенес данные в один RAID-массив объемом 6 ТБ. Затем я воссоздал два индекса, что заняло довольно много времени (если предположить, что у меня есть данные (для таблиц и индексов), и я вхожу в один и тот же массив, и кажется, что с RAID у меня не может быть быстрого последовательного И случайного ч / б в то же время).
В любом случае после воссоздания индексов он работал очень хорошо в течение недели. В течение недели я медленно выполнял чистку на большом столе, который просто удаляет старые ненужные строки. На данный момент я удалил около 300 миллионов из 6 миллиардов, и мне кажется, что мне еще многое предстоит сделать.
Теперь, после примерно недели бега, он работает очень медленно, и я не уверен, что будет лучше.
Текущая ситуация:
- Двойной Xeon
- 192 ГБ ОЗУ
- Windows Server 2012 с SQL Server 2012
- Процессор достигает 100% (16 ядер) - до замедления использовалось только около 50%
- IO, кажется, не работает слишком усердно (без очереди)
Большая таблица в настоящее время имеет (у меня нет никакой информации о фрагментации до сих пор):
- 1x Кластерный индекс: 48% фрагментации
- 1x некластеризованный индекс: фрагментация 36%
- 1x некластеризованный индекс: 10% фрагментация
- Раньше у меня было еще два индекса в этой таблице, но я их недавно отбросил
Как вы думаете, лучше всего решить мою проблему
- Перестройте некластеризованные индексы в том же массиве (предположим, что это должно решить проблему, но потребуется много времени, как и раньше. Вероятно, в ближайшем будущем возникнет та же проблема, что и я до сих пор очищаю таблицу)
- Перестройте некластеризованные индексы на новом массиве RAID (следует исправить, как указано выше, но может быть быстрее)
- Переместите некластеризованные индексы в новый массив RAID (самый быстрый вариант)
- Воссоздайте два старых индекса в новом RAID-массиве (не уверен, уменьшает ли это нагрузку на процессор или ввод-вывод)
Вызывают ли фрагментированные индексы более высокую загрузку процессора?
Что-нибудь еще, что я мог бы пропустить?
ТИА
1 ответ
Исходя из степени фрагментации ваших индексов, вы должны пойти дальше и перестроить их. Любой индекс с фрагментацией более 30% должен быть перестроен. Я также хотел бы убедиться, что вы регулярно обновляете статистику в таблице (перестройка индекса сделает это автоматически).
После этого, если вы по- прежнему видите действительно высокий уровень загрузки ЦП и подтвердили, что это процесс SQLServr.exe, вы захотите сузить круг запросов, использующих большую часть ЦП, и устранить их оттуда.
Вы можете выполнить что-то вроде следующего запроса, чтобы получить сводные данные о запросах, которые используют больше всего ЦП:
SELECT TOP 5 total_worker_time/execution_count AS [Avg CPU Time],
total_logical_writes as [Total Writes],
total_logical_reads as [Total Reads],
SUBSTRING(st.text, (qs.statement_start_offset/2)+1,
((CASE qs.statement_end_offset
WHEN -1 THEN DATALENGTH(st.text)
ELSE qs.statement_end_offset
END - qs.statement_start_offset)/2) + 1) AS statement_text
FROM sys.dm_exec_query_stats AS qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) AS st
ORDER BY total_worker_time/execution_count DESC;
Для данных в реальном времени вы также можете запустить что-то вроде этого:
SELECT er.session_id, er.cpu_time, er.reads, er.writes,
SUBSTRING(st.text, (er.statement_start_offset/2)+1,
((CASE er.statement_end_offset
WHEN -1 THEN DATALENGTH(st.text)
ELSE er.statement_end_offset
END - er.statement_start_offset)/2) + 1) AS statement_text
FROM sys.dm_exec_requests AS er
CROSS APPLY sys.dm_exec_sql_text(er.sql_handle) as st
WHERE session_id > 50
AND status = 'runnable'
ORDER BY cpu_time desc
Вы также можете запустить оба, чтобы сравнить в режиме реального времени для агрегирования данных. Оба должны дать вам представление о том, что использует так много процессора. Оттуда вы захотите узнать, почему они так долго бегают. Они делают тонны чтения или тонны записей? Если они делают кучу операций чтения, это может означать, что им не хватает некоторых индексов. Тонны записей могут означать, что индексы на самом деле являются проблемой.
В любом случае, следя за этими утверждениями, вы можете получить отправную точку.