Присоединение к таблице календаря

#sql #sql-server #database #performance

#sql #sql-сервер #База данных #Производительность

Вопрос:

Я создал таблицу календаря (с индексами), которая содержит даты, день недели, финансовый год, название дня и т.д. Диапазон в моей таблице календаря находится между 2005 и 2071 годами. У меня не возникает никаких проблем при запросе таблицы календаря.

Я хочу использовать столбец даты в таблице календаря для фильтрации 2 разных столбцов даты в 2 разных таблицах.

Проблема, с которой я сталкиваюсь, заключается в том, что при поиске в большом диапазоне дат с использованием столбца даты в таблице календаря (т. е. 2010-2019) для возврата результатов требуется ОЧЕНЬ много времени. Принимая во внимание, что если я запрашиваю один и тот же диапазон дат в каждой таблице, результаты возвращаются за считанные секунды. Вот запрос, с которым я работаю:

 Select 
      a.Col1, 
      a.Col2, 
      a.Col3, 
      a.Date1, 
      b.Date1 
   From 
      TableA as A
         FULL JOIN TableB as B 
            on A.Col1 = B.Col1
            INNER JOIN TableCal as C 
               on A.Date1 = C.Date1 
               or B.Date1 = C.Date1
   WHERE 
      C.date1 between '2010' and '2019'
  

Если есть лучший способ написать это или если я иду по этому пути неправильно, я открыт для всех советов / предложений! Спасибо!

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

1. Начните здесь с того, как получить помощь при медленном запросе . Кроме того, хотя вы уже создали свою собственную, вы можете счесть таблицу календаря Аарона Бертрана более полезной / более динамичной. Также от Аарона, убедитесь, что вам действительно нужен NOLOCK и поймите, почему это может быть плохой идеей. Это не кнопка «перейти быстрее».

2. Прежде всего, удалите эти NOLOCK подсказки. Они не заставляют что-либо работать быстрее. Во-вторых, есть ли индексы в столбцах вашей таблицы календаря? Если нет, то это будет медленно. Наконец, опубликуйте фактический запрос. То, что вы опубликовали здесь, не объединяет даты и фильтрует Date столбец по строке года. Предполагается, что таблица календаря должна иметь отдельные поля для каждого элемента date, и поле date должно быть date . Если WHERE c.date between '2010' and '2019' не выдает ошибку, это, вероятно, потому, что date значения были неявно преобразованы в строки, что привело к полному сканированию таблицы

3. Примеры данных и желаемые результаты действительно помогли бы. FULL OUTER JOIN редко требуется.

4. C.date1 действительно является переменной года?

5. исправление «c.date между ‘2010’ и ‘2019’» решило проблему. Похоже, задержка была вызвана полным сканированием таблицы. Спасибо! @PanagiotisKanavos

Ответ №1:

Формально ответ заключается в использовании equijoins, подобных этому:

 Select a.Col1, a.Col2, a.Col3
From (a join
      cal ca 
      on a.col2 = ca.col2
     ) full join
     (b join
      cal cb
      on b.col2 = cb.col2
     ) 
     on a.col1 = b.col1
where ca.date between '2010' and '2019' or
      cb.date between '2010' and '2019' ;