Объединение MySQL запросов, один из которых является запросом исключения - PullRequest
0 голосов
/ 22 апреля 2020

Первый вопрос здесь, поэтому я прошу прощения, если я пропустил что-то ранее заданное, или не отформатировал это хорошо ... У моей компании есть собственная база данных CRM +, которую я пытаюсь улучшить. Нам нужно найти список свойств, для которых не будет продлен ежегодный сервис. В настоящее время мы делаем это, сначала находя свойства, для которых будет обновлена ​​их служба, что делается с помощью следующего запроса:

SELECT DISTINCT 
  j.`property_id` 
FROM
  `jobs` AS j 
  LEFT JOIN `property` AS p 
    ON j.`property_id` = p.`property_id` 
  LEFT JOIN `agency` AS a 
    ON p.`agency_id` = a.`agency_id` 
  INNER JOIN `property_services` AS ps 
    ON (
      j.`property_id` = ps.`property_id` 
      AND j.`service` = ps.`alarm_job_type_id`
    ) 
WHERE ps.`service` = 1 
  AND a.`country_id` = 1 
  AND (
    j.`status` = 'Pending' 
    OR j.`date` IS NULL 
    OR j.`date` = '0000-00-00' 
    OR j.`job_type` = 'Once-off' 
    OR j.`job_type` = '240v Rebook' 
    OR (
      j.`date` >= '2019-04-22' 
      AND j.`job_type` = 'Yearly Maintenance'
    )
  )

Затем мы находим детали, которые мы хотим отобразить для пользователя, исключая другие элементы в процесс:

SELECT DISTINCT 
  j.`property_id`,
  p.`address_1` AS p_address1,
  p.`address_2` AS p_address2,
  p.`address_3` AS p_address3,
  p.`state` AS p_state,
  p.`postcode` AS p_postcode,
  a.`agency_id`,
  a.`agency_name` 
FROM
  `jobs` AS j 
  LEFT JOIN `property` AS p 
    ON j.`property_id` = p.`property_id` 
  LEFT JOIN `agency` AS a 
    ON p.`agency_id` = a.`agency_id` 
  INNER JOIN `property_services` AS ps 
    ON (
      j.`property_id` = ps.`property_id` 
      AND j.`service` = ps.`alarm_job_type_id`
    ) 
WHERE p.`property_id` NOT IN (INSERT HERE THE IDS YOU GOT FROM THE FIRST QUERY) 
  AND ps.`service` = 1 
  AND p.`deleted` = 0 
  AND p.`agency_deleted` = 0 
  AND a.`status` = 'active' 
  AND a.`country_id` = 1 
ORDER BY j.`property_id` DESC 
LIMIT 0, 50 

В идеале я хотел бы объединить эти запросы или как-то оптимизировать их, поскольку загрузка страницы в настоящее время занимает более 2 минут, даже с индексированием. Опять же, мои извинения, я не эксперт по базам данных или запросам, почти уверен, что степень включала только один или два предмета по этому вопросу!

1 Ответ

0 голосов
/ 08 мая 2020

Для справки (на случай, если кто-то сочтет это полезным), комбинированная версия:

    SELECT DISTINCT 
  j.`property_id`,
  p.`address_1` AS p_address1,
  p.`address_2` AS p_address2,
  p.`address_3` AS p_address3,
  p.`state` AS p_state,
  p.`postcode` AS p_postcode,
  a.`agency_id`,
  a.`agency_name` 
FROM
  `jobs` AS j 
  LEFT JOIN `property` AS p 
    ON j.`property_id` = p.`property_id` 
  LEFT JOIN `agency` AS a 
    ON p.`agency_id` = a.`agency_id` 
  INNER JOIN `property_services` AS ps 
    ON (
      j.`property_id` = ps.`property_id` 
      AND j.`service` = ps.`alarm_job_type_id`
    ) 
WHERE p.`property_id` NOT IN 
  (SELECT DISTINCT 
    j.`property_id` 
  FROM
    `jobs` AS j 
    LEFT JOIN `property` AS p 
      ON j.`property_id` = p.`property_id` 
    LEFT JOIN `agency` AS a 
      ON p.`agency_id` = a.`agency_id` 
    INNER JOIN `property_services` AS ps 
      ON (
        j.`property_id` = ps.`property_id` 
        AND j.`service` = ps.`alarm_job_type_id`
      ) 
  WHERE ps.`service` = 1 
    AND a.`country_id` = 1 
    AND (
      j.`status` = 'Pending' 
      OR j.`date` IS NULL 
      OR j.`date` = '0000-00-00' 
      OR j.`job_type` = 'Once-off' 
      OR j.`job_type` = '240v Rebook' 
      OR (
        j.`date` >= '2019-05-08' 
        AND j.`job_type` = 'Yearly Maintenance'
      )
    )) 
  AND ps.`service` = 1 
  AND p.`deleted` = 0 
  AND p.`agency_deleted` = 0 
  AND a.`status` = 'active' 
  AND a.`country_id` = 1 
  AND (
    j.`status` != 'Booked' 
    AND j.`status` != 'To Be Booked' 
    AND j.`status` != 'Send Letters' 
    AND j.`status` != 'On Hold' 
    AND j.`status` != 'On Hold - COVID' 
    AND j.`status` != 'Pre Completion' 
    AND j.`status` != 'Merged Certificates'
  ) 
  AND j.`date` > DATE_ADD(NOW(), INTERVAL - 350 DAY) 
ORDER BY j.`property_id` DESC

Кто-то за пределами StackOverflow помог объединиться, но это не помогло ... В итоге мы получили добавить маркер и выполнить его поиск, потому что для выполнения этого запроса в нашей базе данных потребовалось 193 секунды.

Кроме того, я полностью получил требование предоставить минимальный воспроизводимый пример, и я виноват в том, что не сделал этого.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...