Внутренний запрос или несколько запросов, которые приведут к лучшей производительности для mysql? - PullRequest
0 голосов
/ 11 марта 2020

Внутренний запрос:

select up.user_id, up.id as utility_pro_id from utility_pro as up
join utility_pro_zip_code as upz ON upz.utility_pro_id = up.id and upz.zip_code_id=1
where up.available_for_survey=1 and up.user_id not in (select bjr.user_id from book_job_request as bjr where 
((1583821800000 between bjr.start_time and bjr.end_time) and (1583825400000 between bjr.start_time and bjr.end_time)))

Разделенный на два запроса:

  1. select up.user_id, up.id as utility_pro_id from utility_pro as up join utility_pro_zip_code as upz ON upz.utility_pro_id = up.id and upz.zip_code_id=1

  2. Select bjr.user_id as userId from book_job_request as bjr where bjr.user_id in :userIds and (:startTime between bjr.start_time and bjr.end_time) and (:endTime between bjr.start_time and bjr.end_time)

Примечание : Насколько я понимаю, когда один запрос будет выполнен с использованием внутреннего запроса, он будет сканировать все данные book_job_request, но при использовании нескольких запросов Будут проверяться строки с указанными идентификаторами пользователя.

Также приветствуется любой другой лучший вариант для той же операции, кроме этих двух.

Ответы [ 2 ]

1 голос
/ 11 марта 2020

Я ожидаю, что запрос должен выглядеть примерно так:

SELECT up.user_id
     , up.id utility_pro_id 
  FROM utility_pro up
  JOIN utility_pro_zip_code upz 
    ON upz.utility_pro_id = up.id
  LEFT
  JOIN book_job_request bjr 
    ON bjr.user_id = up.user_id
   AND bjr.end_time >= 1583821800000
   AND bjr.start_time <= 1583825400000
 WHERE up.available_for_survey = 1 
   AND upz.zip_code_id = 1
   AND bjr.user_id IS NULL

Для дальнейшей помощи по оптимизации (то есть, какие индексы нужно предоставить) нам понадобятся операторы SHOW CREATE TABLE для всех соответствующих таблиц, как а также ОБЪЯСНЕНИЕ для вышеупомянутого

0 голосов
/ 21 марта 2020

Другая возможность:

SELECT  up.user_id , up.id utility_pro_id
    FROM  utility_pro up
    JOIN  utility_pro_zip_code upz  ON upz.utility_pro_id = up.id
    WHERE  up.available_for_survey = 1
      AND  upz.zip_code_id = 1
      AND  bjr.user_id IS NULL
      AND NOT EXISTS( SELECT 1 FROM book_job_request
                           WHERE user_id = up.user_id
                             AND end_time   >= 1583821800000
                             AND start_time <= 1583825400000 )

Рекомендуемые индексы (для моего НЕ СУЩЕСТВУЮЩЕГО и для СТРОБЕРБЕРСКОГО ЛЕВОГО СОЕДИНЕНИЯ):

book_job_request:  (user_id, start_time, end_time)
upz:  (zip_code_id, utility_pro_id)
up:  (available_for_survey, user_id, id)

Указанный порядок столбцов важен. И нет, у вас в данный момент одинаковые индексы не так хороши.

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