Занялся оптимизацией продукта, который вот-вот выйдет в свет и над которым я работал последние месяцы. Не с начала, в дизайне архитектуры я участия не принимал, только правил его потом, насколько было возможно.
Так вот, столкнулся с такой ерундой. Есть таблица в БД, одна из основных. В ней находятся миллионы записей и эти миллионы постоянно в работе (то есть, это не логи и не калькуляция, которые можно просчитывать и сохранять как-то еще). Скажем, это сообщения. Тысячи пользователей их шлют друг другу, читают, раскладывают по папкам, пролистывают и т.д.
В таблице этой примерно 1000 (одна тысяча) колонок. В колонках – данные, одна запись в таблице – одно сообщение со всеми-всеми своими атрибутами (коих может быть немерено). Вроде так же делает Sharepoint (не проверял).
Колонки, в целях экономии дискового пространства, почти все (кроме основных: ID, Name, etc) - sparse (это SQL Server 2008 у нас).
Вопрос:
Запросы типа SELECT [Id], [Name], [nVarchar1], [Integer1], [XmlData1], [XmlData3] FROM [Message].[Messages] WHERE TypeID = 3765
приводят к Table Scan. Возможно по причине sparse-колонок, я не уверен. Это происходит даже при наличии индекса на TypeId. Сервер предпочитает не использовать этот индекс. Если же его заставить, то время исполнения запроса только увеличивается.
Понятное дело, что это дело все неприемлемо медленно. Понятное дело, что всё это еще медленнее, если в WHERE появляется что-то более интересное.
Понятно, что при просмотре execution plan оно предлагает построить индекс по TypeId и включить в него все колонки, учавствующие в выборке. Но так, как их тысяча…
Нет, я даже попробовал. Ради интереса. Индекс (некластерный) строился час с лишним. Построился. На времени выборки это практически не сказалось, а вот время апдейта какого-нибудь nVarChar1 для одной строки выросло до 5 секунд! А было мгновенно. И должно быть быстро. Так что такие вот огромные индексы – тоже не панацея.
Может у кого-то есть какие-то идеи или опыт по работе с большими таблицами? Или на предмет как это можно реструктурировать, чтобы было поэффективнее, а?