Уточняющие вопросы
Какова ОСНОВНАЯ часть данных, к которой вы обращаетесь - консультанты, поисковый текст, торговые точки?
Такое ощущение, что ваши критерии позволяютдля пользователей, чтобы искать по-разному.Sproc всегда будет использовать точно такой же план для каждого вашего вопроса.Вы получаете более высокую производительность, используя несколько sprocs - каждый из которых настроен на определенный сценарий поиска (то есть, я уверен, что вы могли бы написать что-то невероятно быстрое для запросов только по номеру политики).
Если вы можете разделить свой текст поиска наИНДИВИДУАЛЬНЫЕ параметры, тогда вы сможете:
- Поиск связей советника, соответствующих вашему предоставленному списку - сохранить во временной таблице (или табличной переменной).
- ЕСЛИ ЛЮБЫЕ фамилии были указаны тогдаудалите все записи из temp, которые не предназначены для людей с указанными вами именами.
- Повторите эти действия для других списков критериев - все время сокращая ваши временные записи.
- ТО присоединитесь к внешнему соединениюи верните результаты.
В своих заметках вы говорите, что торговые точки можно игнорировать.Если это так, то удаление их упростит ваш запрос.Предложение «или» в вашем примере означает, что SQL-серверу необходимо найти ВСЕ отношения для ВСЕХ портфелей, прежде чем он сможет реально приступить к фильтрации тех результатов, которые вам действительно нужны.
Прерываниезапрос вверх
Большинство запросов состоит из внешних объединений, которые не участвуют в фильтрации.Попробуйте переместить эти объединения в отдельный выбор (т. Е. После того, как вы применили все свои критерии).Когда SQL-сервер видит много таблиц, он отключает некоторые из возможных оптимизаций.Таким образом, ваш первый шаг (при условии, что вы всегда указываете советники) просто:
SELECT advRel.SourceEntityId as adviserId,
advRel.TargetEntityId AS rfClientId
INTO #temp1
FROM @AdvisersListing advisers
INNER JOIN tbOP_EntityRelationship advRel
ON advRel.SourceEntityId = advisers.adviser
AND advRel.RelationshipId = 39;
Ссылка на tbOP_Entity (псевдоним "pe") не выглядит так, как будто она необходима для его данных.Таким образом, вы должны иметь возможность заменить все ссылки на «pe.EntityId» на «advRel.TargetEntityId».
Предложение DISTINCT и GROUP-BY, вероятно, пытаются достичь одного и того же - и оба онидействительно дорогоОбычно вы найдете ОДИН из них, когда предыдущий разработчик не смог получить правильные результаты.Избавьтесь от них - проверьте свои результаты - если вы получаете дубликаты, попробуйте отфильтровать дубликаты.Вам может понадобиться ОДНА из них, если у вас есть временные данные - вам определенно не нужны оба.
Индексы
Убедитесь, что столбец @ AdvisersListing.adviser одинаковDateType как SourceEntityId и этот SourceEntityId индексируется.Если столбец имеет другой тип данных, то SQL-сервер не захочет использовать индекс (поэтому вы должны изменить тип данных в @AdvisersListing).
Таблицы tbOP_EntityRelationship звучат так, как будто они должны иметьиндексировать что-то вроде:
CREATE UNIQUE INDEX advRel_idx1 ON tbOP_EntityRelationship (SourceEntityId,
RelationshipId, TargetEntityId);
Если это существует, то SQL-сервер должен иметь возможность получать все, что ему нужно, ТОЛЬКО переходя на страницы индекса (а не на страницы таблиц).Это известно как индекс «покрытия».
Должен быть немного другой индекс для tbOP_Data (при условии, что он имеет кластеризованный первичный ключ в DataId):
CREATE INDEX tbOP_Data_idx1 ON tbOP_Data (entityId) INCLUDE (dateCreated);
SQL-сервер будетхранить ключи из кластерного индекса таблицы (который я предполагаю, будет DataId) вместе со значением «dateCreated» на листах индекса.Итак, снова у нас есть «покрывающий» индекс.
Большинство других таблиц (tbOP__Client и т. Д.) Должны иметь индексы для DataId.
План запроса
К сожалению, я не смог увидеть картину плана объяснения (наш брандмауэр съел ее).Однако один полезный совет - навести указатель мыши на некоторые линии соединения.Он сообщает вам, сколько записей будет доступно.
Остерегайтесь сканирования полной таблицы.Если SQL-серверу нужно их использовать, то он почти полностью отказался от ваших индексов.
Структура базы данных
Он был разработан как база данных транзакций.Уровень нормализации (и все EntityRelationship - this и Data - которые действительно болезненны для отчетности).Вам действительно нужно подумать о том, чтобы иметь отдельную базу данных отчетов, которая распределяет часть этой информации в более удобную структуру.
Если вы запускаете отчеты непосредственно для своей производственной базы данных, я бы ожидал кучу проблем с блокировками и конфликт ресурсов..
Надеюсь, это было полезно - впервые я разместил здесь.Прошло много лет с тех пор, как я в последний раз настраивал запрос в моей нынешней компании (у них есть кучка суровых администраторов баз данных для сортировки такого рода вещей).