#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' ;