Есть у нас на работе, человек с фамилией Гарин. Обожаю в отчетах или в именах файлов воткнуть "2garin" и улыбаться тихо про себя.
А еще - есть таблица с предметами. Есть вторая, с указанием, какой предмет, на какую паллету положили. Есть даже третья, с паллетами, где можно посмотреть, активна паллета или её вернули и помнить о ней не стоит.
Это не я так сделал, это вот так оно есть.
А еще есть задача.
Задача проста и описывается простым вопросом. Сколько предметов зоне производства, и не на активной паллете?
Коза-лось-бы, вопрос простой. Решение - тоже.
Импортируем в datafram`ы все три таблички, мержим/джойним и фильтруем. Задачка на несколько строк.
Да? Да. Но, "НО", разумеется есть.
Это "НО" - количество таких штук. Их почти 300 тысяч и прибавляется ежеминутно. Проверка всех-всех штук занимает более 20 минут.
Как временное решение - оно тихонечко себе считается во временную таблицу, а потом временная таблица заменяется свеженькой, пауза в 2 часа и по новой.
Работает, не поспоришь, но лаг почти в два с половиной часа делает некрасиво.
А тут новости. Оказывается, когда одном сервере, и скрипты, и база данных - мол моветон. Теперь у нас будет новый сервер, с хранилищем и вообще.
С одной стороны - красота. На сервере, который "мой" аж две разные базы. Postgres и MSSql (для связи с 1С) и настраивал я обе, очень сильно на ощупь, оно работает, но как именно работает - я вообще хз, если честно. А тут - ответственный не я. Красота же.
С другой - теперь будет только одна база и она будет MSSql. Жопка, потому что там дебильный синтаксис. Знаешь как будет ограничение на 10 строк? LIMIT 10? Нет, "SELECT TOP 10 * FROM TABLE ORDER BY id". Почему? Ну вот потому что.
И теперь задача становится интереснее. Нужно переписать свои скрипты, чтобы они работали на microsoft SQL.
Короч, всю субботу я провел за тем, чтобы не делать вот то, а делать иначе. Наверняка ведь можно как-то ускорить это всё. Да? Да. У меня было несколько вариантов как это всё делать, с разными успехами. Думал уже делать скрипт, который не создает временную таблицу, а просто проверяет, где ролик и меняет данные в основной таблице, только у тех роликов, которые изменили своё состояние.
И вот прикинул я это, как это вообще писать и сколько времени займет... Решил пойти другим путем, а именно - без временных таблиц. Просто одном запросом к базе.
Оказалось, что тормозит весь этот процесс именно рекурсия. Для каждого ролика, список паллет, для каждой из паллеты проверка активности.
О-коза-лось, что вообще-то в Postgres можно сохранять результаты в переменную, прямо в самом запросе.
Теперь не нужно проверять каждую паллету, если сначала выбрать все активные паллеты в список, а потом проверять паллету в списке.
Оказалось лучше, но всё еще не так хорошо, как хотелось бы.
Совсем хорошо тало, когда я пошел с другой стороны.
1. Взять список всех активных паллет и джойним штуки только на активных паллетах. Сохраняем в временную табличку. Получаем список штук на паллетах.
2. Берем только штуки, которые нужно положить на паллету и сохраняем во временную таблицу. Получаем список штук, который на паллетах должны быть.
3. Джойним одно к другому и фильтруем штуки, которым паллеты не нашлось.
Сколько это делалось раньше? 20 минут. Сколько сейчас? 0,8 секунды.
Мама, чтож я такой тупой?