Меня попросили изучить проблему с производительностью приложения, которое становится все медленнее. Довольно быстро я смог сузить проблему до одной таблицы базы данных. Плохо структурированный код C# Я хорошо оптимизирую. Но с SQL столами я менее уверен. Так что я здесь надеюсь на некоторую помощь!
В рассматриваемой таблице хранятся многоязычные переводы для определенных ключевых слов, используемых в приложении. Это таблица роста. И по мере роста производительность базовых c SELECT и JOIN начинает резко падать. Прямо сейчас в таблице чуть более 1 миллиона записей, что на самом деле не так уж и много.
Например:
SELECT * FROM PE_TranslationPhrase WHERE Phrase = 'ABC-123'
Это может занять от 8 до 32 секунд. завершено.
Таблица размещена на Azure SQL. Вот посмотрите на это в SSMS:
введите описание изображения здесь
Значит, это не такая уж сложная таблица. Структура первичного ключа - это не просто обычное автоматически увеличивающееся целое число. TranslationId
и CultureName
вместе составляют первичный ключ (и это нормально).
При решении проблем с производительностью в первую очередь, конечно же, нужно искать индексы. Вот что сейчас находится в таблице:
CLUSTERED:
- [TranslationId] ASC,
- [CultureName] ASC
STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF
и
NON-CLUSTERED:
- [CultureName] ASC,
- INCLUDE ([Phrase])
STATISTICS_NORECOMPUTE = OFF, DROP_EXISTING = OFF, ONLINE = OFF
Причина для НЕКЛАСТЕРИРОВАННОГО индекса с Phrase
и CultureName
заключается в том, что все эти столбцы используются время фильтров и объединений. Пример:
LEFT JOIN
PE_TranslationPhrase TP
ON A.Description COLLATE Latin1_General_CS_AS = TP.Phrase COLLATE Latin1_General_CS_AS
AND A.CULTURENAME = TP.CultureName
ЧТО Я ПРОВЕРИЛ И ВОПРОСЫ:
Я попытался восстановить индексы:
ALTER INDEX ALL ON dbo.PE_TranslationPhrase REBUILD
Это не помогло Похоже, это не оказывает заметного влияния на производительность.
Мой вопрос: плохо ли иметь CultureName
как часть обоих индексов? Как я могу / должен изменить эти индексы?
Спасибо !!