Как переписать этот вложенный запрос? - PullRequest
0 голосов
/ 03 декабря 2011

Синтаксис этого запроса

SELECT * FROM  table1
WHERE var_c IN(
SELECT var_a FROM table2 
WHERE var_b =55554444
);

Эквивалентен этому?

SELECT table1.* FROM table1, table2
WHERE (table2.var_a=table1.var_c AND table2.var_b=55554444);

Первый из них занимает около 7-8 секунд, а второй - около 0,75секунды, чтобы бежать.Когда я использую оператор Join, для его выполнения требуется около 4-5 секунд.

Также синтаксис этого

DELETE FROM  table1
WHERE var_c IN(
SELECT var_a FROM table2 
WHERE var_b =55554444
);

И такой:

DELETE table1.* FROM table1, table2
WHERE (table2.var_a=table1.var_c AND table2.var_b=55554444);

то же самое?

Ответы [ 3 ]

3 голосов
/ 03 декабря 2011

Нет, 2 запроса не эквивалентны. Второй может возвращать повторяющиеся строки, если (var_a, var_b) не UNIQUE в table2

Первый запрос:

SELECT * 
FROM  table1
WHERE var_c IN
      ( SELECT var_a 
        FROM table2 
        WHERE var_b =55554444
      )

и если table2.var_a не содержит значений NULL, то это эквивалентно следующему:

SELECT table1.* 
FROM table1
   , table2
WHERE table2.var_a = table1.var_c 
  AND table2.var_b = 55554444
GROUP BY table1.PK                --- Primary Key of table1

(что лучше записать с явным синтаксисом JOIN как:

SELECT table1.* 
FROM table1
  JOIN table2
    ON table2.var_a = table1.var_c 
WHERE table2.var_b = 55554444
GROUP BY table1.PK                --- Primary Key of table1

и это:

SELECT * 
FROM  table1
WHERE EXISTS 
      ( SELECT *
        FROM table2 
        WHERE table2.var_b = 55554444
          AND table2.var_a = table1.var_c
      )

Что касается производительности, лучший совет, который вы можете получить, это проверить, протестировать и протестировать снова с вашими данными. Попробуйте с разными индексами и выясните, как читать планы EXPLAIN.

Вы, вероятно, обнаружите, что IN (SELECT ... FROM ...) имеет не самую лучшую производительность с текущим оптимизатором MySQL (хотя я слышал, что MariaDB планирует некоторые важные улучшения в следующем выпуске, Maria 5.3) и что варианты JOIN и EXISTS работают обычно лучше.

Но это сильно зависит от индексов, которые у вас есть в таблицах. Без какого-либо индекса все они будут медленными. И query time < 1 sec не означает, что это быстро. Да, с миллиардом строк в таблицах, это довольно хорошо. Для таблицы с несколькими тысячами строк следует ожидать time < 0.01 sec.

1 голос
/ 03 декабря 2011

Этот запрос недействителен DELETE * FROM table1, используйте DELETE FROM table1

1 голос
/ 03 декабря 2011

Попробуйте использовать внутреннее соединение :

SELECT * FROM  table1
INNER JOIN table2
ON table2.var_a = table1.var_c
WHERE table2.var_b =55554444
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...