У меня есть таблица, которая потенциально может хранить сотни тысяч целых чисел
desc id_key_table;
+----------------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------------+--------------+------+-----+---------+-------+
| id_key | int(16) | NO | PRI | NULL | |
+----------------+--------------+------+-----+---------+-------+
Из программы у меня есть большой набор целых чисел. Я хотел бы видеть, какие из этих целых чисел НЕ в приведенном выше столбце id_key.
До сих пор я придумал следующие подходы:
1) Переберите каждое целое число и выполните:
select count(*) count from id_key_table where id_key = :id_key
Когда счетчик равен 0, id_key отсутствует в таблице.
Это кажется ужасным, ужасным способом сделать это.
2) Создайте временную таблицу, вставьте каждое из значений во временную таблицу и выполните JOIN для двух таблиц.
create temporary table id_key_table_temp (id_key int(16) primary key );
insert into id_key_table_temp values (1),(2),(3),...,(500),(501);
select temp.id_key
from id_key_table_temp temp left join id_key_table as main
on temp.id_key = main.id_key
where main.killID is null;
drop table id_key_table_temp;
Это кажется лучшим подходом, однако я уверен, что есть гораздо лучший подход, о котором я еще не думал. Я бы предпочел не создавать временную таблицу и использовать один запрос, чтобы определить, какие целые числа отсутствуют.
Есть ли правильный запрос для этого типа поиска?
(Баз данных)
Ответы:
Ваше второе решение с использованием LEFT JOIN является наилучшим подходом. Я не буду использовать временную таблицу, я буду использовать обычную таблицу и заполнять ее новыми значениями в любое время, когда вы захотите выполнить запрос.
источник
Похоже, «большой набор целых чисел» все еще значительно меньше таблицы с «сотнями тысяч целых чисел». С учетом этого предположения, и если в MySQL нет способа использовать массив ваших целых чисел в качестве таблицы в вашем операторе SQL, ваш второй вариант, вероятно, является лучшим. Следует выполнить полное сканирование временной таблицы и индекса главной таблицы. Основное преимущество заключается в том, что ему нужно только один раз сканировать индекс, содержащий сотни тысяч целых чисел, и только отправлять клиенту результаты. Ваш запрос может (но не обязательно) быть переписан следующим образом:
источник
Вместо временной таблицы и вставки с помощью
insert into id_key_table_temp values (1),(2),(3),...,(500),(501);
вы можете создать подзапрос со всеми значениями, которые вы пытаетесь проверить:источник
Как отмечено в моем комментарии, это, вероятно, больше подходит для stackoverflow. Тем не менее, я думаю, что оба эти решения не являются лучшими:
Решение 1 требует многократных вызовов, очень неэффективно
Решение 2 лучше, но я не уверен, что затраты на вставку такого количества значений - лучшее решение.
Возможным решением 3 было бы сделать один запрос:
и программно получить разницу от вашего набора целых и того, что находится в БД. В худшем случае (так как в нем много целых чисел), этот маршрут должен быть лучше, чем в решении 1. Решение 2 может также ТАКЖЕ возвращать много целых чисел (если в таблице есть набор, которого нет в вашем наборе данных), поэтому зависит ™!
источник
Я в значительной степени обратился к этому в StackOverflow , но я хотел бы подробнее остановиться на использовании таблицы постоянных временных переменных (PermTemp). ( постоянный темп, разве это не оксюморон ?)
В StackOverflow у меня была хранимая процедура test.CreateSampleTable и test.GetMissingIntegers создают примерную таблицу, а затем создают динамическую временную таблицу для заполнения перед выполнением большого JOIN для поиска различий.
На этот раз давайте создадим образец таблицы вместе с таблицей постоянных таблиц.
Вот test.LoadSampleTables:
После запуска вот таблицы и их содержимое:
Вот триггеры для таблицы PermTemp
Теперь давайте импортируем новый пакет записей, таблицу test.weekly_batch, некоторые ключи, которые использовались ранее, другие ключи совершенно новые:
Давайте возьмем test.weekly_batch и безопасно объединим его с test.id_key_table_keys и сформируем таблицу test.new_keys_to_load:
Вот результат:
С этого момента просто используйте таблицу new_keys_to_load в качестве списка брендов, порождающих новые ключи для импорта. Поскольку new_keys_to_load меньше, чем таблица PermTemp, вы всегда должны использовать new_keys_to_load в левой части LEFT JOIN.
источник