SQL-запрос выполняется очень медленно при использовании функции форматирования даты - PullRequest
2 голосов
/ 04 июля 2019

Использование SQL Server 2016. У меня есть следующая таблица с большим количеством записей (30 мил +).

CREATE TABLE [dbo].[TABLE1]
(
    [DATE_TIME] [DATETIME] NULL,
    [TEXT] [VARCHAR](500) NULL,
    [MSG] [VARCHAR](500) NULL,
    [MSGID] [INT] NULL,
    [SEVERITY] VARCHAR(50) NULL
)

CREATE NONCLUSTERED INDEX [TABLE1_IX1] 
ON [dbo].[TABLE1] ([DATE_TIME] ASC, [MSGID] ASC, [SEVERITY] ASC)
                WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF,  
                      SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, 
                      ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]

Следующий запрос очень медленный:

SELECT 
    [DATE_TIME], [TEXT], [MSG], [MSGID], [SEVERITY] 
FROM      
    [TABLE1] 
WHERE
    FORMAT([DATE_TIME], 'yyyy-MM-dd') IN ('2019-06-25', '2019-06-24',etc.....) 
    AND [MSGID] IN (8016, 11, 3072, 23, 3062, etc....) 
    AND [SEVERITY] <> 'Medium' 
ORDER BY 
    [DATE_TIME] DESC

Пожалуйста, помогите оптимизировать.

Ответы [ 3 ]

2 голосов
/ 04 июля 2019

Формат обладает отличной функциональностью, но производительность может снизиться.

Попробуйте

WHERE convert(date,[DATE_TIME]) in (...)
1 голос
/ 04 июля 2019

Использовать прямые сравнения дат.Поскольку у вас, кажется, есть диапазон, я бы порекомендовал:

WHERE [DATE_TIME] >= ? AND
      [DATE_TIME] < '2019-06-26' AND
      [MSGID] IN (8016, 11, 3072, 23, 3062, etc....) AND
      [SEVERITY] <> 'Medium' 

Это может обеспечить оптимальное использование индекса и разделов, если они доступны.Вы также можете конвертировать в date.Это единственное использование функции, которая также будет использовать индекс.Я не знаю, удалит ли конвертер разделы.

1 голос
/ 04 июля 2019

Вы упомянули, что столбец DATE_TIME содержит часть времени. В этом случае я бы предложил создать постоянный вычисляемый столбец, содержащий только часть даты:

X_DATE AS CAST(DATE_TIME AS DATE) PERSISTED

И индексируйте его, и используйте его внутри предложения where:

WHERE [X_DATE] IN ('2019-06-25', '2019-06-24') 
  AND [MSGID] IN (8016, 11, 3072, 23, 3062) 
  AND [SEVERITY] <> 'Medium' 
...