копировать подмножество строк из одной таблицы в другую, фильтруя по двум столбцам - PullRequest
3 голосов
/ 29 сентября 2011

У меня есть следующая таблица MySql, содержащая мои необработанные данные о событиях (около 1,5 миллионов строк)

userId  | pathId  | other stuff....

У меня есть индекс на userId, pathId (около 50 000 уникальных комбинаций)

Во время обработки я определяю 30 000 userId, pathId значений, которые мне не нужны, но я хочу сохранить исходную необработанную таблицу. Поэтому я хочу скопировать все строки в обработанную таблицу событий, кроме строк, которые соответствуют этим 30 000 userId, pathId значениям.

Подход, который я рассматриваю, состоит в том, чтобы записать 30 000 userId,PathId значений строк, которые я не хочу, в temp_table, а затем сделать что-то вроде этого:

[create table processed_table ...]
insert into processed_table 
   select * from raw_table r 
   where not exists (
       select * from temp_table t where r.userId=t.userid and r.pathId=t.pathId
   )

Для справки, processed_table обычно в два раза меньше, чем raw_table.

В любом случае, это похоже на работу, но мои навыки SQL ограничены, поэтому мой вопрос (наконец-то) - это самый эффективный способ сделать это?

1 Ответ

4 голосов
/ 29 сентября 2011

Нет, это не самый эффективный. Источник

Вот почему лучший способ поиска пропущенных значений в MySQL - это использовать LEFT JOIN / IS NULL или NOT IN вместо NOT EXISTS.

Вот пример с NOT IN:

INSERT INTO processed_table 
SELECT *
FROM raw_table 
WHERE (userId, pathId) NOT IN (
    SELECT userId, pathId FROM temp_table
)

И LEFT JOIN ... IS NULL:

INSERT INTO processed_table 
SELECT *
FROM raw_table r
LEFT JOIN temp_table t
ON r.userId = t.userid AND r.pathId = t.pathId
WHERE t.userId IS NULL

Однако, поскольку ваша таблица очень мала и содержит только 50 000 строк, ваш исходный запрос, вероятно, достаточно быстрый.

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