Как оптимизировать внутренний запрос mysql

#mysql #ruby-on-rails

#mysql #ruby-on-rails

Вопрос:

 insert into abc(id,item_id,item_type,l_id,c_id)
Select '',o.id,'Open',pl.id,'67' from pls pl, opens o where o.id IN
(select id from Open where not exists (select 1 from ps where type = 'Open' and item_id = opens.id)) and o.type = pl.name;
  

У меня огромные данные..
Буду признателен за помощь!!!

Ответ №1:

Для выбора переключения использования IN на joins:-

 SELECT DISTINCT '', o.id, 'Open', pl.id, '67' 
FROM pls pl
INNER JOIN opens o ON and o.type = pl.name
INNER JOIN open op ON and o.id = op.id
LEFT OUTER JOIN ps ON ps.type = 'Open' and ps.item_id = opens.id
WHERE ps.item_id IS NULL
  

Я добавил DISTINCT на случай, если идентификатор в открытой таблице не уникален. Если он уникален, то это можно опустить.

ЛЕВОЕ ВНЕШНЕЕ СОЕДИНЕНИЕ проверяет наличие соответствующей записи в таблице PS, и если она есть, возвращается. В противном случае столбцы из этой таблицы возвращаются как NULL. Затем в предложении WHERE ненулевые значения опущены из результатов.

Однако для эффективности важны индексы в таблицах. Есть ли индекс по типу в таблице opens? Индекс по идентификатору в открытой таблице? Тип покрытия индекса и item_id в таблице ps?

Комментарии:

1. Да, у меня есть индекс для всех заданных полей. мы дважды использовали внутреннее соединение, можем ли мы выполнить его за одно соединение… Я не имею большого представления о внутреннем соединении, пожалуйста, игнорируйте, если это звучит глупо

2. Он использует ВНУТРЕННЕЕ СОЕДИНЕНИЕ один раз для каждой таблицы. Единственный способ избежать этого — использовать, IN(SELECT....) который, как правило, плохо оптимизирован в MySQL или EXISTS(SELECT....) , который в данном случае, я думаю, вероятно, будет работать плохо из-за необходимости коррелированного подзапроса (т. Е. подзапрос проверяет значение извне запроса и должен выполняться для каждой строки).

3. Мой последний запрос — ВСТАВИТЬ В ps (id, em_id, em_type, l_id, c_id) SELECT «,o.id ,’Открыть’,pl.id ’67’ ИЗ pls pl INNER JOIN открывает o НА o.type = pl.name ВНУТРЕННЕЕ СОЕДИНЕНИЕ открывается на o.id = opens.id ГДЕ НЕ СУЩЕСТВУЕТ (ВЫБЕРИТЕ 1 Из ps, ГДЕ em_type = ‘Open’ И em_id = opens.id );

4. Проблема в том, что вложенный запрос, который вы используете для NOT EXISTS, ссылается на opens.id. Поэтому его нужно будет выполнять много раз (решение LEFT OUTER JOIN позволяет избежать этого).

5. Привет, Kickstart У меня более сложный запрос, чем приведенный выше — Где есть 5 таблиц Table A => Field id, Table B => Fields id, a_id, c_id, Table C => Fields id, name, Table D => Fields id, name, Table E => Field id, a_id, d_id Из A нужно получить B, … из B нужно C name,… Затем сравните имя C с именем D и получите идентификатор D …. если равно, то создайте записи a в E с a_id и d_id. Не могли бы вы, пожалуйста, помочь мне в получении запроса из inner join

Ответ №2:

Попробуйте это:

   insert into abc(id,item_id,item_type,l_id,c_id)
  Select '',o.id,'Open',pl.id,'67' from pls pl
  INNER JOIN opens o ON o.type = pl.name 
  INNER JOIN open ON  o.id = open.id 
  where not exists (select 1 from ps where type = 'Open' and item_id = opens.id)