Уж больно медленный запрос, какие у меня варианты? - PullRequest
1 голос
/ 24 марта 2020

Я делаю sql работу в больнице (пока нет случаев COVID!). Существует таблица, [dbo].A.diagnosis, которая содержит историю всех диагнозов всех наших пациентов. Я не эксперт, но стол ... плохо. Он используется этим древним программным обеспечением, которое мы здесь используем для диагностики (среди прочего). Как работает таблица, она имеет более 30 столбцов и более 300 тысяч строк, но не имеет индекса (кроме как по первичному ключу). Каждый раз, когда пациент получает обновленный диагноз, все его диагнозы записываются в таблицу под новым diagnosis_date. diagnosis_date хранится в типе данных date вместо datetime, но пациент нередко обновляет диагноз несколько раз в день.

Мне нужно получить список всех наших текущих -принимал пациентов, и должен ли он быть достаточно актуальным (я бы сказал, что в течение последних 24 часов это разумно, но предпочтительнее раньше).

Мой текущий лучший запрос все еще сильно варьируется во время выполнения, принимая от 1 до 15 (!!!) минут до запуска. Это неприемлемо, поэтому я хочу знать, какие у меня есть варианты для его улучшения.

Образец данных (вымышленный, только соответствующие столбцы):

-- [dbo].A.diagnosis
+------------+----------------+----------------+----------------+-----------------------------+
| patient_id | diagnosis_type | diagnosis_date | diagnosis_code | diagnosis_text              |
+------------+----------------+----------------+----------------+-----------------------------+
| 0369344991 | I              | 2020-01-04     | E669           | Obesity, unspecified        |
| 0369344991 | I              | 2020-01-04     | M545           | Low back pain               |
| 0369344991 | I              | 2020-01-04     | NULL           | NULL                        | -- Separator
| 0369344991 | U              | 2020-01-04     | E669           | Obesity, unspecified        |
| 0369344991 | U              | 2020-01-04     | M545           | Low back pain               |
| 0369344991 | U              | 2020-01-04     | L709           | Acne, unspecified           | -- Updated later that day to add the acne diagnosis
| 0369344991 | U              | 2020-01-04     | NULL           | NULL                        |
| 0369344991 | U              | 2020-01-16     | E669           | Obesity, unspecified        |
| 0369344991 | U              | 2020-01-16     | L709           | Acne, unspecified           |
| 0369344991 | U              | 2020-01-16     | E785           | Hyperlipidemia, unspecified | -- Updated 12 days later, low back pain resolved, added hyperlipidemia
| 0369344991 | U              | 2020-01-16     | NULL           | NULL                        |
+------------+----------------+----------------+----------------+-----------------------------+

-- [dbo].A.patients
+------------+
| patient_id |
+------------+
| 0369344991 |
+------------+

-- [dbo].B.diagnosis_priority
+----------------+--------------------+
| diagnosis_type | diagnosis_priority |
+----------------+--------------------+
| I              | 1                  |
| A              | 2                  |
| U              | 3                  |
| D              | 4                  |
+----------------+--------------------+

Запрос:

SELECT DISTINCT dx.patient_id -- (decimal(10,0), null)
,       dx.diagnosis_date -- (date, null)
,       dx.diagnosis_code -- (varchar(5), null)
,       dx.diagnosis_text -- (varchar(253, null) 
,       dx.diagnosis_type -- (varchar(1), null)
FROM    [dbo].A.patients -- Starting with a list of our current patients.
JOIN    [dbo].A.diagnosis dx
    ON  [dbo].A.patients.patient_id = dx.patient_id
JOIN    [dbo].B.diagnosis_priority dp 
    ON  dx.diagnosis_type = dp.diagnosis_type
-- This is a table I wrote to help determine which diagnoses are more 'up-to-date' if multiple updates are done on 
-- a single day. The join assigns a priority number to each diagnosis_type as diagnosis_priority.
WHERE   dx.diagnosis_code IS NOT NULL
AND     dx.diagnosis_date = ( -- Trying to get the diagnoses as of the most recent diagnosis date.
            SELECT  MAX(dx_a.diagnosis_date) 
            FROM    [dbo].A.diagnosis dx_a 
            WHERE   dx_a.patient_id = dx.patient_id
            ) 
AND     dp.diagnosis_priority = (  
-- Trying to get the highest priority diagnoses applied on the most recent date.
-- A patient will not get a lower priority diagnosis on a later date, but newer diagnoses will not 
-- necessarily get a higher priority in [dbo].A.diagnosis
            SELECT  MAX(dp_a.diagnosis_priority) 
            FROM    [dbo].A.diagnosis dx_a 
            JOIN    [dbo].B.diagnosis_priority dp_a 
                ON dx_a.diagnosis_type = dp_a.diagnosis_type 
            WHERE dx_a.patient_id = dx.patient_id
            )

Я являюсь членом db_datareader на [dbo].A, но я являюсь членом db_owner на [dbo].B на том же сервере. Изменение способа [dbo].A.diagnosis функций невозможно из-за вышеупомянутого древнего программного обеспечения.

Если запрос не может быть значительно улучшен, я хочу знать, какие опции у меня есть на [dbo].B для поддержки список текущих диагнозов для пациентов, которые в настоящее время находятся в больнице.

1 Ответ

1 голос
/ 25 марта 2020

Потоковая передача всех данных во временную таблицу и выполнение запроса к временной таблице.

CREATE TABLE #diagnosis_tmp (patient_id decimal(10,0), diagnosis_type varchar(1), diagnosis_date date, diagnosis_code varchar(5), diagnosis_text varchar(253))

INSERT INTO #diagnosis_tmp (patient_id,diagnosis_type,diagnosis_date,diagnosis_code)
SELECT patient_id,diagnosis_type,diagnosis_date,diagnosis_code
FROM [dbo].A.diagnosis
    WHERE diagnosis_code IS NOT NULL

--CREATE INDEX i_patient_date ON #diagnosis_tmp (patient_id,diagnosis_date)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...