Народ, поделитесь успешными реализациями такой вещи как:
Выгрузка данных из базы по множественным условиям (не знаю как правильно назвать).
Наприер, нужно выгрузить из базы 500.000 книг. У нас есть только ID (AI или MongoDB\BSON\ObjectID) этих книг.
Я думал 1 вариант, это разбиение 500.000 на итерации выгрузки по 1000, и писать стандартный .. in ($ids). Но все равно очень много запросов будет..
Кто как делает? Куда копать?)
Множествоенное обновление и выгрузка
- Cacatuidae
- Сообщения: 65
- Зарегистрирован: 2017.01.08, 17:39
- Cacatuidae
- Сообщения: 65
- Зарегистрирован: 2017.01.08, 17:39
Re: Множествоенное обновление и выгрузка
Аналогично и потребуется еще обновлять. Мол выгрузить, и обновить потом.
Обновляться будет у всех одно и тоже поле с оним и тем же значением.
Выгрузили 500.000 книг, изменили поле и нужно обновить их же.
Обновляться будет у всех одно и тоже поле с оним и тем же значением.
Выгрузили 500.000 книг, изменили поле и нужно обновить их же.
- Cacatuidae
- Сообщения: 65
- Зарегистрирован: 2017.01.08, 17:39
Re: Множествоенное обновление и выгрузка
Мини иследование по селекту по первому вопросу.
$ids = Массив 50,000 ID
Если делать напрямую
Такие результаты:
1. Создать таблицу
2. Заполнить ее массив $ids
3. Добавить в основную выборку
То получаю такие результаты:
Иследование продолжается
Update1:
Вся непосредственная выборка упирается в процессор. А именно в одно ядро в случае с INNODB.
Никакие nnodb_thread_concurrency не помогут, т.к. если я правильно понял, то innoDB на 1 запрос использует 1 ядро процессора
$ids = Массив 50,000 ID
Если делать напрямую
Код: Выделить всё
...
$query->where(['id' => $ids]);
...
Если делать через временную таблицу в такой последовательности:Память: 27,64 МБ
MAX память: 818,794 МБ
17 секунд
1. Создать таблицу
Код: Выделить всё
CREATE TEMPORARY TABLE IF NOT EXISTS `{$tableName}` (id int(11) NOT NULL, INDEX (id))
Код: Выделить всё
$db->createCommand()->batchInsert($table, ['id'], $ids)->execute();
Код: Выделить всё
...
$query->where(['id' => $db->createCommand("select `id` from `{$table}`")->queryColumn()]);
...
По времени получается почти одинаково, но вот в потребление памяти второй вариант выгоднее первогоПамять: 28,401 МБ
MAX память: 71,836 МБ
16 секунд
Иследование продолжается
Update1:
Вся непосредственная выборка упирается в процессор. А именно в одно ядро в случае с INNODB.
Никакие nnodb_thread_concurrency не помогут, т.к. если я правильно понял, то innoDB на 1 запрос использует 1 ядро процессора
Re: Множествоенное обновление и выгрузка
вот так можно ещё попробовать https://github.com/yiisoft/yii2/blob/ma ... я-выборка-
Re: Множествоенное обновление и выгрузка
Используйте курсоры для выгрузки. Прочитали одну строку - звписали в файл или сделали update и т.д. Расход памяти будет минимальным. Запрос будет один. Если используете PDO и MySQL, в PDO нужно задать специальную опцию: http://php.net/manual/ru/mysqlinfo.conc ... fering.php
Если про yii, то делаете по ссылке выше. Однако там не сказано, что построчное получение результата надо сначала как правило включить в драйвере. Более того, он должен это поддерживать. Если просто сделать как в примере в книге, все равно PDO сначала загрузит все в память.
Если про yii, то делаете по ссылке выше. Однако там не сказано, что построчное получение результата надо сначала как правило включить в драйвере. Более того, он должен это поддерживать. Если просто сделать как в примере в книге, все равно PDO сначала загрузит все в память.