Оптимизирует ли mysql предложение IN

Когда я выполняю этот запрос mysql, например

select * from t1 where colomn1 in (select colomn1 from t2) ,

что на самом деле происходит?

Я хочу знать, выполняется ли внутренний оператор для каждой строки?

PS: у меня 300 000 строк в t1 и 50 000 строк в t2, и это занимает чертовски много времени.


person user217869    schedule 19.05.2014    source источник
comment
сделайте индекс столбца1 или уникальное поле в таблице t1 и столбец1 в таблице t2, это очень поможет   -  person uvais    schedule 19.05.2014
comment
я использовал соединение в первую очередь, но это тоже не сработало   -  person user217869    schedule 19.05.2014
comment
как не работал? был медленным? вернул разные данные? как уже упоминалось, индексация поможет для соединений и для подзапросов   -  person Milan Halada    schedule 19.05.2014
comment
возможный дубликат подзапроса v/s внутреннего соединения на сервере sql   -  person Milan Halada    schedule 19.05.2014
comment
@Uriel_SVK это было медленно... я подождал 2-3 минуты... потом отменил запрос..   -  person user217869    schedule 19.05.2014
comment
@user217869 user217869 вы используете какие-нибудь индексы? У вас должны быть индексы как минимум на t1.column1 и t2.column1. Также лучше использовать JOIN   -  person Milan Halada    schedule 19.05.2014
comment
индексация работает, но я хочу знать, что на самом деле происходит, когда этот запрос выполняется!!   -  person user217869    schedule 05.04.2015


Ответы (4)


Я ошеломлен, увидев, что все указывают на использование JOIN, как будто это одно и то же. ЭТО НЕТ!, не с информацией, представленной здесь. Например. Что, если у t2.column1 есть двойники?

=> Предполагая, что в t2.column1 нет двойников, тогда да, поместите UNIQUE INDEX в указанный столбец и используйте конструкцию JOIN, поскольку она более удобочитаема и проста в обслуживании. Если это будет быстрее; это зависит от того, что делает из него механизм запросов. В MSSQL оптимизатор запросов (вероятно) считал бы их одним и тем же; возможно, MySQL «не так стремится» распознать это... не знаю.

=> Предполагая, что в t2.column1 могут быть двойники, поместите (неуникальный) INDEX в указанный столбец и перепишите WHERE IN (SELECT ..) в WHERE EXISTS ( SELECT * FROM t2 WHERE t2.column1 = t1.column1). Опять же, в основном для удобочитаемости и простоты обслуживания; скорее всего, механизм запросов будет относиться к ним одинаково...

Вещи, которые нужно помнить,

  • Всегда следите за правильностью индексации (но не переусердствуйте)
  • Всегда помните, что то, что происходит на самом деле, будет интерпретацией вашего sql-кода; не "прямой перевод". Вы можете написать одну и ту же функциональность по-разному для достижения одной и той же цели. И некоторые из них действительно более устойчивы к различным сценариям.

Если у вас всего 10 строк, почти все работает. Если у вас есть 10 миллионов строк, возможно, стоит изучить план запроса... который, скорее всего, будет отличаться от плана с 10 строками.

person deroby    schedule 31.05.2014

Присоединение будет быстрее, а именно:

select t1.* from t1 INNER JOIN t2 on t1.colomn1=t2.colomn1
person Philip Sheard    schedule 19.05.2014

Попробуйте с ВНУТРЕННИМ СОЕДИНЕНИЕМ

SELECT t1.*
FROM t1
INNER JOIN t2 ON t1.column1=t2.column1
person Sadikhasan    schedule 19.05.2014

Вы должны выполнить индексирование в столбце1, а затем вы можете использовать внутреннее соединение для индексирования

CREATE INDEX index1 ON t1 (col1);
CREATE INDEX index2 ON t2 (col2);
select t1.* from t1 INNER JOIN t2 on t1.colomn1=t2.colomn1
person Ronak Shah    schedule 19.05.2014