Как повысить производительность извлечения даты и времени из строки в SQL Server 2008R2? - PullRequest
0 голосов
/ 30 апреля 2019

Я работаю над задачей переноса данных (SSIS), использую базу данных SQL 2008, где мне нужно извлечь дату и время из строки и преобразовать их в поле типа данных datetime, чтобы потом можно было вставить его в таблицу.

У меня есть функция SQL, сохраненная в базе данных, которую я использую в запросе, и она правильно анализирует строку, чтобы вывести правильные результаты. Единственная серьезная проблема заключается в том, что запрос занимает около полутора часов, чтобы получить около 120 000 записей. Если можно, пожалуйста, укажите правильное направление, если мне нужно исправить свой запрос или функцию, чтобы значительно повысить производительность.

Запрос, в котором я использую функцию синтаксического анализа строки (fnExtrDateTimeFromString), равен

select
case when dbo.fnExtrDateTimeFromString(NoteList.Item) is null then CAST('2000-01-01 00:00:00.000' as datetime)
     when CAST(dbo.fnExtrDateTimeFromString(NoteList.Item) as date) = CAST('1900-01-01' as date) then dbo.fnExtrDateTimeFromString(NoteList.Item)+CAST('2000-01-01 00:00:00.000' as datetime)
     else dbo.fnExtrDateTimeFromString(NoteList.Item) end as NoteDate,
CAST(LTRIM(RTRIM(NoteList.Item)) as text) as UsersNotes
from UserNotes
cross apply convDelimitedSplit(UserNotes.NoteText,',') as NoteList
where LEN(ISNULL(UserNotes.Notes,'')) > 0

Внутри функции fnExtrDateTimeFromString я использую 2 табличные переменные для хранения всех шаблонов формата даты и времени, а затем использую patindex для последующего объединения как строки даты и времени, так и конкатенации к полю даты и времени. Это 300-строчная функция, которую я не знаю, я могу вставить сюда.

Пример строки: 'Пользователь appt: 7/27/94 @ 10:30 AM', а дата будет 27.07.1994 и время 10:30. Это строки пользовательского ввода, поэтому они очень противоречивы в отношении пробелов и разделяющих символов. Example string and output

1 Ответ

2 голосов
/ 30 апреля 2019

Как @Shnugo указал, что вы вызываете эту "дорогую" функцию несколько раз для каждой строки.

Чтобы убедиться, что сделан только один вызов, используйте подзапрос:

select
    case when NoteDate is null then CAST('2000-01-01 00:00:00.000' as datetime)
        when NoteDate = CAST('1900-01-01' as date) then NoteDate + CAST('2000-01-01 00:00:00.000' as datetime)
        else NoteDate
    end as NoteDate,
    UsersNotes
from    
    ( select
        dbo.fnExtrDateTimeFromString(NoteList.Item) as NoteDate,
        CAST(LTRIM(RTRIM(NoteList.Item)) as text) as UsersNotes
    from UserNotes
        cross apply convDelimitedSplit(UserNotes.NoteText,',') as NoteList
    where LEN(ISNULL(UserNotes.Notes,'')) > 0 ) as a

Примечание: text тип данных устарел, вы должны использовать VARCHAR (MAX)

Если эта функция разделения даты является узким местом производительности, она должна удвоить / утроить производительность.

Хорошо прочитано: https://sqlperformance.com/2014/06/t-sql-queries/dirty-secrets-of-the-case-expression

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...