Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > PHP: Базы Данных > Оптимальная по скорости выборка из большой таблицы


Автор: teroni 10.6.2011, 18:22
Задача такая. Есть таблица в mysql с 5 000 000 записей. Одно из полей в этой таблице уникальное, назовём его unique.
И есть массив из 5 000 строк. Нужно из этого массива выбрать те строки, которые не совпадают ни с одним из значений поля unique той таблицы.

Как это сделать оптимально по времени и ресурсам?
У меня несколько версий.
1) Выгрузить все 5 000 000 записей из базы в массив и сравнить массивы с помощью array_diff().
2) Пробежаться по каждой из 5000 строк массива и сделать для неё запрос mysql типа 
Код

SELECT * FROM `table` WHERE `unique` = '$string'

3) Создать ещё одну mysql таблицу, набить в неё эти 5000 строк, затем сделать запрос с LEFT JOIN первой таблицы и этой временной таблицы.

Какой вариант лучше? Или может есть ещё какой-то, о котором я не знаю/забыл?

Автор: triclosan 10.6.2011, 23:03
#3 но мне кажется можно начать с более примитивного запроса

Код

select *
from `array_t`
where val not in (
select unique
from `table`
)


не забыть сделать так, если индекса нет
Код

CREATE UNIQUE  INDEX id_index ON table (unique)



Автор: teroni 11.6.2011, 00:10
Да я тоже остановился на 3-м варианте... Работает, но хотелось бы побыстрее, чем сейчас.

Автор: triclosan 11.6.2011, 01:10
1,2 будут в разы медленнее, имхо.

средняя длина строки какая?

Автор: teroni 11.6.2011, 11:38
triclosan, 20 символов.

Автор: triclosan 11.6.2011, 16:14
Это априори долго будет, например выполнить СИшный strcmp 25 000 000 000 раз со строками 20 символов займет немало времени. Обрисуйте вашу задачу подробнее может можно добиться цели переделав логику.

Автор: teroni 11.6.2011, 21:20
Цитата(triclosan @  11.6.2011,  16:14 Найти цитируемый пост)
Это априори долго будет, например выполнить СИшный strcmp 25 000 000 000 раз со строками 20 символов займет немало времени. Обрисуйте вашу задачу подробнее может можно добиться цели переделав логику. 

Да всё вроде бы подробно в первом сообщении. 5 млн - это исходная база, она относительно неизменна, уникальное поле - это типа имени записи. А те 5 тысяч строк - они получаются из файла пользователя, я не могу заранее знать, что там будет, но мне нужно выбирать только те строки, которых нету в 5 млн базе. Естественно, в пользовательском файле не всегда 5 тыс строк, может быть и меньше, это я с запасом взял. Ну в принципе, у меня на локалке уже за 1 минуту делается расчёт, думаю на хостинге с более мощным серваком будет нормально, т.к. другой алгоритм я всё равно не придумаю.

Автор: triclosan 11.6.2011, 21:46
такая мысль пришла - снять со всех 5М crc16 (или даже более короткую чек-сумму), при наполнении таблицы со строками пользователей считать чек-сумму налету. Естественно это ускорит выборку, результаты выборки можно дополнительно проверить на случай коллизий - такой запрос будет быстрым по сравнению с полным перебором

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)