почему использование предложения IN (или NOT IN) в запросе делает его очень медленным

У меня есть запрос:

SELECT DISTINCT field1 FROM table1 WHERE field2 = something

(таблица 1 содержит 1 миллион записей, время выполнения: 0,106 с, возвращает: 20 записей)

Другой запрос

SELECT DISTINCT similarField1 FROM table2 WHERE similarField2 = somethingElse

(таблица2 содержит полмиллиона записей, время выполнения: 0,078 с, возвращает: 20 записей)

Теперь, если я запускаю запрос, комбинируя вышеперечисленное:

SELECT DISTINCT field1 FROM table1 WHERE field2 = something AND field1 NOT IN (SELECT DISTINCT similarField1 FROM table2 WHERE similarField2 = somethingElse)

Это не дает результата даже в течение 10 минут. Почему это стало резко медленным, и что может быть потенциальным решением.

изменить: я использую MySQL с dbvisualizer 6.5


person Anil Bhaskar    schedule 09.02.2015    source источник
comment
Что это, MySql или MS SQL-Server?   -  person Tim Schmelter    schedule 09.02.2015
comment
MySQL, извините за удаление тега sql-server   -  person Anil Bhaskar    schedule 09.02.2015
comment
Это медленно, потому что MySQL. Вы можете попытаться LEFT JOIN выбрать два варианта и вернуть только те строки, где совпадений нет. (leftjoinedquery.field1 имеет значение null).   -  person GolezTrol    schedule 09.02.2015
comment
Я согласен с GolezTrol. Если это возможно, вы должны присоединиться к столам.   -  person Charlie Vieillard    schedule 09.02.2015
comment
спасибо Голез! Я попробовал SELECT DISTINCT field1 FROM table1 LEFT OUTER JOIN table2 ON table1.field1 = table2.similarField1 WHERE table1.field2 = something AND table2.similarField2 = somethingElse, конечно, это увеличило скорость (заняло 35 секунд), но не дало желаемого результата.   -  person Anil Bhaskar    schedule 09.02.2015


Ответы (2)


Вам не нужно использовать DISTINCT в подзапросе. Попробуйте использовать NOT EXISTS, который, вероятно, более эффективен в SQL-сервере:

SELECT DISTINCT field1 
FROM   table1 
WHERE  field2 = @something 
AND NOT EXISTS
(
    SELECT 1 FROM table2
    WHERE table2.similarfield1 = table1.field2 
     AND  table2.similarfield2 = @somethingelse
)

Изменить: поскольку вы обновили теги, я не уверен, что это более эффективно в MySql. Однако я бы все равно предпочел NOT EXISTS, так как он также работает с NULL значениями< /a>(если вы используете IS NULL), его легче читать и поддерживать.

person Tim Schmelter    schedule 09.02.2015

мой вопрос и совет аналогичны @TimSchmelter.

На самом деле вы вообще не должны использовать отличные друг от друга. Сначала вы должны удалить отдельные и проверить, не получаете ли вы дубликаты записей, которые вы просто задаете часть своей проблемы. Дизайн таблицы не ясен.

Вы должны опубликовать свою полную проблему и запрос здесь без каких-либо колебаний. Также не забудьте применить индекс к feild2, feild1,similarField1,similarField2.

SELECT DISTINCT field1
FROM table1 tbl1
WHERE field2 = something
    AND NOT EXISTS (
        SELECT similarField1
        FROM table2 tbl2
        WHERE tbl1.field1 = tbl2.similarField1
            AND similarField2 = somethingElse
        )
person KumarHarsh    schedule 09.02.2015
comment
Благодарю. Дизайн стола простой, больше и говорить не о чем... наверное. Попробовал ваше решение, но не помогло, оно продолжает работать даже через 10 минут. Я думаю, левое внешнее соединение может помочь. - person Anil Bhaskar; 09.02.2015