Оптимизация запросов группового запроса - PullRequest
1 голос
/ 03 ноября 2019

У меня есть следующая схема базы данных -

shop_orders(id, project_id, selling_price, tax_amount, ...)

project_contacts(id, project_id, contact_id, ...)

projects(project_id, project_contact_id, site_contact_id, ...)

Пример данных -

shop_orders(1, 123456, 24.35, 2.34, ...)
project_contacts(1, 123456, 10001, ...)
projects(123456, 10001, 10002, ...)

Желаемый вывод -

123456:26.69

Я пытаюсь выполнить следующий запрос-

SELECT GROUP_CONCAT(CONCAT(project_id, ':', (`selling_price` + `tax_amount`))) AS project_amount 
FROM shop_orders 
WHERE project_id IN (
   SELECT project_id FROM project_contacts WHERE contact_id=10001 
   UNION SELECT project_id FROM projects WHERE project_contact_id=10001 
   UNION SELECT project_id FROM projects WHERE site_contact_id=10001 
)

Этот запрос работает нормально на демо-сервере, у которого размер таблицы проектов около 800, в то время как он не работает на рабочем сервере [т.е. он просто продолжает работать в состоянии зомби], который имеет таблицу проектовразмер ~ 9000

Пожалуйста, дайте мне знать о том, как оптимизировать запрос.

РЕДАКТИРОВАТЬ

Даже этот запрос не возвращает никакого ответа -

SELECT CONCAT(project_id, ':', (`selling_price` + `tax_amount`)) AS project_amount 
FROM shop_orders 
WHERE project_id IN (
  SELECT project_id FROM project_contacts WHERE contact_id=10001 
  UNION SELECT project_id FROM projects WHERE project_contact_id=10001 
  UNION SELECT project_id FROM projects WHERE site_contact_id=10001
)

хотя, если я запускаю запрос, подобный -

SELECT CONCAT(project_id, ':', (`selling_price` + `tax_amount`)) AS project_amount 
FROM shop_orders WHERE project_id IN (NULL)

, он сразу же возвращает ответ. Также другой запрос на объединение также выполняется довольно хорошо отдельно. Я могу выполнить оба запроса по отдельности, но не уверен, почему один запрос не возвращает вывод.

1 Ответ

1 голос
/ 03 ноября 2019

Я бы начал с формулировки запроса, используя EXISTS:

SELECT GROUP_CONCAT(CONCAT(project_id, ':', (`selling_price` + `tax_amount`))) AS project_amount 
FROM shop_orders so
WHERE EXISTS (SELECT 1
              FROM project_contacts pc
              WHERE pc.project_id = so.project_id AND
                    pc.contact_id = 10001
             ) OR
      EXISTS (SELECT 1
              FROM project p
              WHERE p.project_id = so.project_id AND
                    p.project_contact_id = 10001
             ) OR
      EXISTS (SELECT 1
              FROM project p
              WHERE p.project_id = so.project_id AND
                    p.site_contact_id = 10001
             );

Для оптимальной производительности вам нужны следующие индексы:

  • project_contacts(project_id, contact_id)
  • project(project_id, projecct_contact_id)
  • project(project_id, site_contact_id)

Следует отметить, что CONCAT() избыточен в GROUP_CONCAT(), потому что он принимает несколько аргументов:

SELECT GROUP_CONCAT(project_id, ':', (`selling_price` + `tax_amount`)) AS project_amount 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...