У меня возникли проблемы с оптимизацией сложного представления в MS SQL

#sql #sql-server #join #optimization #view

#sql #sql-server #Присоединиться #оптимизация #Вид

Вопрос:

Я пытаюсь создать представление для объединения иерархических данных с нормализованным набором данных в SQL с использованием поля ProfileID.

Проблема, с которой я сталкиваюсь, заключается в том, что данные иерархии моей компании, из-за отсутствия лучшего термина, ограничены. Существуют поля startdate и enddate, которые необходимо учитывать при объединении.

В настоящее время я работаю с чем-то вроде следующего —

 Select * from 
dbo.datatable dt
inner join dbo.hierarchy h
on dt.profileid = h.profileid
AND dt.date >= h.startdate
AND dt.date < h.enddate
 

У меня есть кластеризованный индекс dt , который включает date и profileid и кластеризованный индекс h , который включает startdate , enddate , и profileid . SSMS также предложила пару индексов, которые я также добавил, которые включают в себя множество полей данных.

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

Любые советы приветствуются!

Комментарии:

1. Рассмотрите возможность изменения порядка кластеризованного индекса, чтобы profileid он был первым.

2. Взгляните на эту статью itprotoday.com/sql-server/interval-queries-sql-server

3. @RickJames не вызовет ли это проблем с эффективностью таблицы данных? В настоящее время это указано в дате заказа, Интервале, ProfileID.

4. @Charlieface Это полная бессмыслица. Оптимизатор может свободно изменять запрос и выполняет — порядок логических выражений, соединенных с помощью «И», не имеет абсолютно никакого значения. Возможно, так будет легче читать и понимать, но оптимизатору все равно.

5. @Smor Извините, я говорил о столбцах ключа индекса. Очевидно, что вы правы в отношении фактического запроса

Ответ №1:

В обеих таблицах укажите profileId первое место в вероятном индексе. Это связано с тем, что он тестируется с. =

Увы, это, вероятно, единственная оптимизация, которую вы можете сделать. Просмотр диапазона дат приводит к использованию только одного из тестов и приводит к сканированию до половины таблицы. Или, после тестирования ProfileID, просканируйте половину строк для этого ProfileID.

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