Сделайте SQL-запрос общим и сделайте его быстрым
Найдя правильный SQL-запрос для моих целей, я понял, что мой запрос медленный.
WITH temp_table (t_col_1, t_col_2, t_col_3) AS
(
SELECT col_1 AS t_col_1, col_2 AS t_col_2, col_3 AS t_col_3
FROM actual_table
WHERE ID = 100 AND PID = 1245
)
SELECT t_col_1, t_col_2, t_col_3
FROM temp_table AS t1
WHERE t1.t_col_2 BETWEEN 1 AND 12541
AND t1.t_col_1 = (SELECT max(t2.t_col_1)
FROM temp_table AS t2
WHERE t2.t_col_1 < 15147
AND t2.t_col_2 = t1.t_col_2)
ORDER BY t1.t_col_2
Причина, по которой я использую запрос в этой форме, заключается в следующем:
- Запрос SQL генерируется и используется в Matlab для извлечения данных.
- В зависимости от идентификатора, столбцы col_1 и col_2 могут быть взаимозаменяемыми, поэтому t_col_1 = col_2 и t_col_2 = col_1. В этом случае скрипт Matlab заменяет col_1 AS t_col_2 и col_2 AS t_col_1.
Есть ли элегантный способ ускорить запрос?
Заранее спасибо.
2 ответа
Ответ полностью зависит от вашего оптимизатора запросов и статистики базы данных, которая, в свою очередь, будет отличаться в зависимости от вашего выбора базы данных.
- Получить QEP - план выполнения запроса
- Посмотрите, где план медленный
- Оптимизируйте запрос и / или добавьте статистику базы данных и / или добавьте необходимые индексы
Вы можете попытаться настроить запрос и, возможно, вам повезет, но правильный подход - понять план запроса.
Например, у вас нет возможности узнать, является ли значение 'max' медленным, или может ли current_table содержать миллиард строк без индекса по ID и PID.
Ваша проблема в том, что запрос относительно максимального значения t_col_1
выполняется для каждой строки, так как ваш основной запрос проверяет WHERE
критерии. Вместо этого вы можете генерировать max(t2.t_col_1)
значение из подзапроса, который выполняется один раз и затем использует эту переменную в ваших критериях, например так:
SELECT PID, t1.t_col_1, t1.t_col_2, t1.t_col_3
FROM
(SELECT PID, t_col_1, t_col_2, t_col_3, max(t2.t_col_1) AS t_col_1_max
FROM temp_table
GROUP BY PID, t_col_1, t_col_2, t_col_3)
as t1
WHERE
(t1.t_col_2 BETWEEN 1 AND 12541)
AND t1.t_col_1 < 15147
AND t1.t_col_1 = t1.t_col_1_max
ORDER BY t1.t_col_2
Ваш код для создания временной таблицы выглядит хорошо.