#c_sharp #entity_framework
Программа парсит через VK API пользователей (в среднем в 20-50 потоков) и создает записи в базе данных. У каждого пользователя в среднем 20 групп, 500 фотографий, 200 друзей. Я храню в разных таблицах записи о друзьях, группах, пользователях и фотографиях. Итого, чтобы сохранить 1го пользователя у меня уходит около 721 запросов на вставку в базу. В минуту это 200-300 пользователей- ~216 000 запросов на вставку в базу. Из за этого вызов context.SaveChanges() отнимает около 6-10 минут на выполнение. Пробовал использовать пул контекстов - bulk insert, среднее время- 4-6 минут. AutoDetectChangesEnabled = false; или context.AddRange() дают примерно те же результаты. Единственное быстрое решение, к которому я пришел - бинарно сериализовывать данные пользователя и хранить их в byte[], чтобы на юзера было 4 запроса вставки. Это сократило время вызова context.SaveChanges() до 1.2 секунды. Но вместе с этим появилась закономерная проблема - чтобы изменить хоть что–то у пользователя, надо десериализовывать и сериализовывать все его данные. Подскажите, какие существуют подходы сохранения больших объемов данных применимые в данном случае не используя сериализацию?
Ответы
Ответ 1
Не нужно вызывать context.SaveChanges() на каждый чих. Вставить 1000 записей за 1 context.SaveChanges() быстрее, чем на каждую запись вызвать context.SaveChanges(). Если у тебя присутсвует какая-то сложная логика, то лучше эту логику вынести в хранимую процедуру. Если БД и приложение находится на разных машинах, то возможно стоит проверить скорость сети. Огромное кол-во индексов может тормозить встаку. Отказаться вообще от EF прии вставках и рулить этим делом через BulkCopy. Например, заливаешь все массово в какую-нибудь таблицу на сервере, затем JOB каждые 5 минут опрашивает эту таблицу и выполняет добавление информации по рабочим таблицам. Еще бы профайлером не помешало бы посмотреть запросы, который формирует EF. Может быть они не оптимальны и стоит пошаманить с LINQ. Я бы посоветовал замерить заполнение БД через BulkCopy(Самый быстрый способ множественных вставок) и тогда ты получишь величину к которой ты должен стримиться и выше которой не прыгнешь, используя EF.
Комментариев нет:
Отправить комментарий