После определенного времени дня - какой метод лучше? - PullRequest
5 голосов
/ 14 мая 2019

Мне нужно знать (и пометить), происходит ли определенное событие в подзапросе после 15:30 (независимо от даты).
С моей настройкой я не смог определить методом пробного использования, который более эффективен (они возвращаются слишком быстро), и план выполнения не помог.

Второй (# 2) кажется мне более эффективным, потому что литерал нужно приводить только один раз (оставляя одну операцию на строку).
Однако иногда подобные операции обманывают, поэтому я надеялся, что кто-нибудь скажет мне, что лучше.

CREATE TABLE #jccTestData([ProcessDate] datetime);
INSERT INTO #jccTestData ([ProcessDate])
VALUES 
    ('2019-03-12 10:23:28.000') ,('2019-03-17 11:22:40.000'), ('2019-03-18 11:25:30.000')
    ,('2019-03-19 11:42:02.000') ,('2019-03-11 12:45:30.000') ,('2019-03-12 13:14:20.000')
    ,('2019-03-13 15:20:13.000') ,('2019-03-14 15:29:40.000') ,('2019-03-15 15:29:59.997') 
    ,('2019-03-16 15:30:00.000') ,('2019-03-17 15:30:00.003') ,('2019-03-18 16:25:30.000')
    ,('2019-03-12 23:59:59.997') ,('2019-03-13 00:00:00.003') ,('2019-03-14 00:00:00.000')
    ,('2019-03-15 03:14:20.000') ,('2019-03-16 05:20:13.000')

SELECT 
    [ProcessDate]
    , Case When datepart(HH, [ProcessDate]) > 15
        OR (datepart(HH, [ProcessDate]) = 15 And datepart(n, [ProcessDate]) >= 30) 
        Then 'After 3:30 PM' 
        End As [After 3:30? #1]
    , Case When cast([ProcessDate] As time) >= cast('15:30:00' As time) 
        Then 'After 3:30 PM' 
        End As [After 3:30? #2]
FROM #jccTestData  
ORDER BY [ProcessDate]

DROP TABLE #jccTestData

Второй также кажется более понятным.

Если есть третий вариант, я тоже открыт для этого.
SQL Server 2012+

Ответы [ 3 ]

2 голосов
/ 14 мая 2019

Поскольку вы спрашиваете об эффективности, я сделал несколько тестов для более миллиона реальных записей.Последний метод (CAST), как показано ниже, сообщает больше процессорного времени.Время указывалось в миллисекундах, поэтому вам понадобятся миллионы записей, чтобы заметить разницу.

IIF((DATEPART(HH, dateStamp) * 60) + DATEPART(MINUTE, dateStamp) >= 930, 'After 3:30 PM', '')
IIF(DATEPART(HH, dateStamp) > 15 OR (DATEPART(HH, dateStamp) = 15 AND DATEPART(N, dateStamp) >= 30), 'After 3:30 PM', '')
IIF(CAST(dateStamp AS TIME) >= CAST('15:30:00' AS TIME), 'After 3:30 PM', '')

1) Среднее время ЦП: 477;Среднее затраченное время: 242

2) Среднее время процессора: 469;Среднее затраченное время: 236

3) Среднее время процессора: 808;Среднее затраченное время: 413

2 голосов
/ 14 мая 2019

Лично, если вы можете, я бы на самом деле добавил вычисляемый столбец в вашу таблицу.CONVERT / CAST к типу данных time - определенно путь при использовании этого маршрута, но если вы можете добавить постоянный вычисляемый столбец, то вы можете проиндексировать этот столбец или добавить его к существующим, иподдерживать SARGability, если вам когда-нибудь понадобится запросить эти данные в WHERE (я понимаю, что образец здесь - временная таблица, но я сомневаюсь, что реальный сценарий таков):

ALTER TABLE #jccTestData ADD ProcessTime AS CONVERT(time,ProcessDate) PERSISTED;

Тогда вы можете просто запросить этоновый столбец:

SELECT [ProcessDate],
       CASE WHEN ProcessTime >= '03:30' THEN 'After 3:30 PM' END AS [After 3:30?]
FROM #jccTestData
ORDER BY [ProcessDate];

Кроме того, избегайте использования порядковых номеров для столбцов в ORDER BY, вам гораздо лучше использовать фактическое имя столбцов.

Примечание, выне нужно иметь столбец для приведения / преобразования в тип данных date.CONVERT(date,ProcessDate) и CAST(ProcessDate AS date) оба SARGable.

0 голосов
/ 14 мая 2019

Я бы использовал третий вариант apply, если вы действительно не изменили структуру DB:

SELECT d.[ProcessDate],
       (CASE WHEN dd.ProcessTime >= '15:30' THEN 'After 3:30 PM' END) AS [After 3:30?]
FROM #jccTestData d CROSS APPLY
     ( VALUES (CONVERT(TIME, ProcessDate)) 
     ) dd (ProcessTime )
ORDER BY d.[ProcessDate];
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...