#sql #postgresql
#sql #postgresql
Вопрос:
У меня есть запрос, выполнение которого занимает много времени. Я не уверен, как мне уменьшить это. Не только время, этот запрос также требует от PSQL высокой загрузки процессора.
Я должен выбрать один столбец sip_username
в качестве разных имен в разных условиях. Из-за этого требования у меня есть подзапросы create,
Запрос является :
SELECT sip_username,
product_code,
display_name as dname,
user_id as uid,
location_id,
tenant_id,
(
SELECT sip_username
FROM admin_users_product
WHERE (sip_username = A.sip_username) AND
(product_code = 'bizfms')
) AS bizfms_username,
(
SELECT sip_username
FROM admin_users_product
WHERE (sip_username = A.sip_username) AND
(product_code = 'mlc')
) AS mlc_username,
(
SELECT sip_username
FROM admin_users_product
WHERE (sip_username = A.sip_username) AND
(product_code = 'bizrtm')
) AS bizrtm_username
FROM admin_users_product AS A
WHERE A.location_id = 18
Что я должен изменить, чтобы сделать это быстрее?
Комментарии:
1. Пожалуйста, удалите тег:
sql-server
.2. Пожалуйста, выполните запрос с префиксом
EXPLAIN (ANALYZE, BUFFERS)
и добавьте выходные данные к вашему вопросу. Это поможет показать вам, как самостоятельно решать подобные проблемы в будущем.3. Каков первичный ключ таблицы
admin_users_product
? Будет ли условиеa.location_id = 18
возвращать несколько строк с разнымиproduct_code
иsip_username
значениями?4. Не могли бы вы опубликовать образцы данных и ожидаемый результат для них? Было бы гораздо легче помочь вам.
5. Ваши подзапросы не имеют смысла. Условие возврата строки заключается в том,
sip_username = A.sip_username
чтобы sip_username, возвращаемое для каждого подзапроса, было идентичным тому, вa.sip_username
котором у вас уже есть. Итак, я не понимаю, чего вы пытаетесь достичь с помощью подзапросов. Похоже, вы можете легко просто удалить их
Ответ №1:
Вы можете попробовать этот код:
SELECT sip_username,
product_code,
display_name as dname,
user_id as uid,
location_id,
tenant_id,
(CASE product_code
WHEN 'bizfms' THEN
sip_username
ELSE Null
END) AS bizfms_username,
(CASE product_code
WHEN 'mlc' THEN
sip_username
ELSE Null
END) AS mlc_username,
(CASE product_code
WHEN 'bizrtm' THEN
sip_username
ELSE Null
END) AS bizrtm_username
FROM admin_users_product AS A
WHERE A.location_id = 18
Ответ №2:
Вы должны создать индекс для некоторого столбца
- Создайте индекс в таблице admin_users_product по столбцам location_id и sip_username
- Создайте индекс в таблице admin_users_product по столбцам sip_username и product_code
и тогда ваш запрос выполняется быстрее…
Ответ №3:
Вы можете попробовать это. В случае, если индекс не существует, вам нужно создать в соответствии с указаниями Мирнамика Абдуллаева.
SELECT sip_username,
product_code,
display_name as dname,
user_id as uid,
location_id,
tenant_id,
B.sip_username bizfms_username,
C.sip_username mlc_username,
D.sip_username bizrtm_username,
FROM admin_users_product AS A
left join admin_users_product B
on A.sip_username = B.sip_username and B.product_code = 'bizfms'
left join admin_users_product C
on A.sip_username = C.sip_username and C.product_code = 'mlc'
left join admin_users_product D
on A.sip_username = D.sip_username and D.product_code = 'bizrtm'
WHERE
A.location_id = 18;