2015-12-16 2 views
1

Можно ли оптимизировать этот запрос?Оптимизация SQL Firebird

SELECT 
    s.event_id as "id", 
    s.event_start as "start", 
    p.treatment_id as "treatment_id", 
    s.status_id as "status_id" 
FROM 
    SCHEDULEREVENT s 
    LEFT JOIN PATIENT_HAS_EVENT p ON p.event_id = s.event_id 
WHERE 
    p.patient_id = 50 

p.event_id является Первичный ключ. Есть индекс на p.patient_id

Выполнение занимает около секунды, что слишком долго для моих нужд.

EDIT: Лучшим решением было сделать этот запрос в обратном направлении с изменением LEFT JOIN в JOIN.

SELECT 
    s.event_id as "id", 
    s.event_start as "start", 
    p.treatment_id as "treatment_id", 
    s.status_id as "status_id" 
FROM 
    PATIENT_HAS_EVENT p 
    JOIN SCHEDULEREVENT s ON s.event_id = p.event_id 
WHERE 
    p.patient_id = 50 

Среднее время выполнения был сбит с 912 мс до 10,69 мс

+0

Поскольку это означает, что 'LEFT JOIN' в вашем коде неявно преобразуется обратно в' INNER JOIN', включив условие в внешнюю объединенную таблицу в предложение WHERE. Это то, что вы намеревались? –

+0

@MarkBannister Я не очень хорошо разбираюсь в базах данных, и я не понимаю, что вы говорите. Вы предлагаете выбрать из таблицы, используемой в разделе 'WHERE', а затем' JOIN' другую таблицу? –

+0

Знаете ли вы, что запрос * предполагается * делать? Вы уверены, что это то, что он * делает? –

ответ

3

ли это "назад":

SELECT 
    s.event_id as "id", 
    s.event_start as "start", 
    p.treatment_id as "treatment_id", 
    s.status_id as "status_id" 
FROM 
    PATIENT_HAS_EVENT p 
    JOIN SCHEDULEREVENT s ON p.event_id = s.event_id 
WHERE 
    p.patient_id = 50 
+0

Большое спасибо. Ваш ответ снизил среднее время выполнения от 912 мс до 12 мс. Является ли общим правилом избегать предложений WHERE, которые ссылаются на объединенные таблицы? –

+0

Собственно, выше комментарий был основан на 'LEFT JOIN'. Используя ваше предложение с 'JOIN', он теперь работает в среднем на 10,69 мс. –

+0

Я не думаю, что это необходимо, чтобы избежать ГДЕ, но вам нужно подумать, что движок действительно делает. Обычно я стараюсь сначала выбрать наименьший объем данных и только после этого начать добавлять данные из других таблиц. Использование внутреннего соединения приведет к тому, что движок, вероятно, сделает то же самое, сохранив запрос, возможно, более логичным. – Harriv

1

Или сделать это с "INNER JOIN".

«ОТ ГРАФИЧЕСКОГО ВСПОМОГАТЕЛЬНОГО ВСПОМОГАТЕЛЬНОГО ПАЦИЕНТА_HAS_EVENT» получает все записи из SCHEDULEREVENT, затем присоединяется к PATIENT_HAS_EVENT, затем применяет где.

Решение Harriv сначала применяется там, где на PATIENT_HAS_EVENT, затем присоединяется к SCHEDULEREVENT.

Использование «INNER JOIN» заставит двигатель выбрать тот же план, что и решение Harriv (я думаю ...).

Смежные вопросы