Коллеги, добрый день!

Вопрос: есть ли какая-то объективная причина того, что в БД террасофта ни в одной таблице абсолютно не используются кластерные индексы?

У нас система еле шевелится, при том что очень мощный сервер БД, всего около 150 пользователей, таблицы не сказать что очень огромные (десятки-сотни тыс. записей)... кроме таблиц логов (миллионы-десятки миллионов записей) :)
В общем производительность очень низкая.

В рамках нашего проекта вопрос построения индексов либо не был запланирован вообще либо был проигнорирован... Единственные индексы, которые построены - некластерные индексы по внешним ключам и по первичному ключу.

Спасибо!

Нравится

9 комментариев

Здравствуйте,
Так сложилось исторически, что для для MSSQL 2000 в общем случае некластерный индекс является оптимальным, так как в Terraosft 3.X для первичных ключей и внешних ключей используются GUID. В этом случае, если включить кластерные индексы, они будут постоянно перестраиваться, т.к. при вставке записей мы всегда получаем случайное значение GUID и для сохранения упорядоченного вида, новую запись нужно вставить в середину индекса.

Для MSSQL 2008, при использовании последовательных GUID, кластерный индекс будет более производительным. В новых версиях мы проанализируем возможность использования таких индексов для MSSQL 2008.

Алексей,

А как на счет использования "разреженных" индексов, в которых FillFactor < 100 (например 60-80)?

Или использование NEWSEQUENTIALID() вместо NEWID()?

Или введения кластерного индекса не связанного с первичным ключем (например, введение поля типа BigInt с автоинкрементом, либо выделение группы полей по которым возможно построить уникальный индекс, например для контрагента - дата создания, наименование, + может быть ИНН, ОГРН)?

Не проводились ли исследования в этой области? Перед тем как начать самому исследование, хотелось бы услышать какие-то рекомендации, наработки, если таковые имеются.

Дело в том что производительность запросов к БД - действительно "больной" вопрос - тут же блокировка таблиц, которая приводит к возникновению дедлоков в случае "тяжелых" запросов, что отчасти на мой взгляд связано с высокой степенью нормализации и недостаточной индексированностью таблиц, т.к. некластерных индексов по внешним ключам явно нехватает...

Тут же возможно возникнут вопросы по сбору статистики для полей как входящих в индексы так и не входящих в них.

Здравствуйте,
1) Генерация самих GUID в Terrasoft 3.X происходит на уровне приложения (используется внутренний генератор Connector.GenGUID()), это дает возможность использовать значения идентификаторов, до их фактической вставки в таблицу, для того что бы использовать последовательную генерацию идентификаторов, необходимо править бинарные файлы, и менять логику построения на генерацию последовательных идентификаторов.

2) Если Вы имеете в виду, замену uniqueidentifier на BigInt, в Terrasoft в качестве первичных ключей, то боюсь Вас разочаровать, многие вещи в конфигурации заточены под использования типа GUID.
В качестве оптимизации вы можете построить группы полей, по которым чаще всего проводиться фильтрация/поиск, и создать кластерный индекс, это действительно может повысить производительность
Последовательные GUID в нашем случае также противоречат репликации – т.к. ключи могут повторяться.

Для начала следует оптимизировать запросы, с которыми в Вашей компании наиболее часто работают.
Для этого выловите сам запрос который идет в БД, SQL Profiler’ом и дальше работу стоит вести по плану выполнения (http://www.mssqltips.com/sqlservertip/1856/sql-server-query-execution-p…)
1

Рассмотрение возможностей оптимизации коробочного продукта, с учетом возможностей SQL Server 2008, запланировано на следующую неделю.

Спасибо, Алексей.

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

"Яворский Алексей" написал: Яворский Алексей 2 апреля 2012 – 15:48

Здравствуйте,
Так сложилось исторически, что для для MSSQL 2000 в общем случае некластерный индекс является оптимальным, так как в Terraosft 3.X для первичных ключей и внешних ключей используются GUID. В этом случае, если включить кластерные индексы, они будут постоянно перестраиваться, т.к. при вставке записей мы всегда получаем случайное значение GUID и для сохранения упорядоченного вида, новую запись нужно вставить в середину индекса.

Тоесть Вы хотите сказать, что Table Scan будет быстрее работать на наблице в 50к записей, чем Clustered Index Scan???

И что RID Lookup работает быстрее, чем Key lookup при использовании индексов???

И таблица с Identity колонкой и кластерным индексом по ней и Nonclustered Primary Key будет работать медленней, чем таблица без кластерного идекса???

Михаил, я думаю Алексей имел ввиду то, что если в качестве первичных и внешних ключей используется guid, то некластерный индекс будет оптимальным.

Универсальное решение тяжело найти, с учетом того что система работает и под FB и Oracle. Не всегда большое кол-во индексов способствует повышению производительности, иногда производительность резко падает из-за переизбытка индексов. Если вы используете MS SQL 2008, то в нем есть хороший инструмент под названием "Мониторинг ресурсов". Он Вам покажет что происходит с диком, процессором и какие тяжелые запросы. На комьюнити выкладывались так же запросы по рекомендациям использования индексов (какие лишниеи каких не хватает). Так же не забывайте каждый день (точнее ночь) перестраивать индексы, чистить кэш (SQL-ный) и собирать статистику.

Евгений, я знаю, что избыток индексов - тоже плохо, я также знаю, что GUID в качестве кластерного индекса тоже плохо, т.к. он быстро фрагментируется.
Я также понимаю, что GUIDы удобнее для разработчиков.
Про мониторинг ресурсов, профайлер, чистку кэша, обновление статистик и др тоже хорошо знаю.
В оптимизации запросов тоже не новичок...

Если вы мне покажете хоть один(!) запрос из нескольких таблиц где записей больше 100 и он будет работать быстрее без кластерных индексов (конечно не по гуиду) я успокоюсь :smile:

Михаил, я не в коем случае не хотел Вас уличить в некомпетентности. Просто я сейчас поддерживаю две крупные базы, каждая из которых примерно 60 Гб. Одна на Oracle, вторая на MS SQL 2008R2. Ни на одной нет кластерных индексов, это не заслуга, просто так исторически сложилось. Сервера работаю в штатном режиме и не особо напрягаются (я не имею ввиду те ситуации когда процесятся OLAP кубы :lol:, но это не часто и не долго). Так вот, основные тормоза идут на конечных рабочих местах при открытии разделов и экранных форм, т.к. ОЧЕНЬ много логики и ОЧЕНЬ много полей, что очень сильно замедляет билдинг и рендеринг клиентского приложения в целом.

"Домброва Михаил" написал:Если вы мне покажете хоть один(!) запрос из нескольких таблиц где записей больше 100 и он будет работать быстрее без кластерных индексов (конечно не по гуиду) я успокоюсь

Такого сравнения не делал. То что он буде работать не медленнее - это точно, но пока обхожусь без него.
Кто знает, может этот момент уже близок, и нужно обязательно переходить на кластерный индекс...

Показать все комментарии