Массовая вставка MySql из огромного массива: вопрос оптимизации - PullRequest
4 голосов
/ 12 июля 2011

Меня попросили выбрать лучший вариант из трех с точки зрения оптимизации ресурсов.Предположим, у меня есть большой файл Excel с тысячами записей, и мне нужно извлечь эти данные и вставить их в базу данных.3 варианта:

  1. Загрузка всего в многомерный массив и вставка всего одним сложным запросом;
  2. Загрузка всего в многомерный массив, затем цикл по каждой строке Excel и выполнениепростой запрос на вставку.
  3. Внутри цикла прочитайте каждую строку Excel, поместите ее в массив и выполните простой запрос на вставку в БД.

Это длятест на собеседование (я назвал это домашним заданием, не уверен, что это правильно);Некоторое время я размышлял:

  • Случай 1 : я мог бы рискнуть ошибкой * out_of_memory * (в зависимости от машины, конечно), но это решение, которое выполняет меньше запросовв базу данных.Два недостатка - огромный объем памяти, выделяемый как для массива, так и для базы данных.Я знаю, что могу превратить Excel в CSV, но это не вариант здесь.Я бы выбрал большой массив и массовую вставку, но боюсь, что для базы данных это будет сложно.
  • Случай 2 : я могу рискнуть ошибкой * out_of_memory * при загрузкев массив, но не для второй задачи.Тем не менее выполнение тысяч запросов может привести к снижению производительности базы данных, и этот запрос может стать кандидатом на оптимизацию.
  • Случай 3 : все еще есть цикл с тысячами записей (который также занимает много памяти ...), и все еще есть тысячи запросов (которые попадают в базу данных).

Итак, я на самом деле выбрал ответ один, и мне пришлось немного подумать, прежде чем это сделать.

И это было НЕПРАВИЛЬНО.И я на самом деле не знаю, какой из трех был правильным.

Может кто-нибудь помочь мне в этом?Это ответ так плохо?Я думал, что тысячи запросов на вставку будут "плохими", но, похоже, я совершенно не прав ..

EDIT Пояснение: мой вопрос не о том, какая из лучших оптимизаций абсолютно , а о том, какой из трех я представил;так что я не смотрю на другие альтернативы, просто объясню, почему я ошибался и что, аргументировано , лучший ответ вместо этого.

Ответы [ 3 ]

3 голосов
/ 12 июля 2011

С одной стороны, это выглядит как вопрос с подвохом. Разумный ответ: используйте утилиту массового импорта, такую ​​как MySQL mysqlimport или SQL Server BULK INSERT ... FROM [data_file]. С другой стороны, эти утилиты, по сути, используют один из трех указанных выше вариантов (хотя, предположительно, с высокой степенью оптимизации).

Дело в том, что вы должны учитывать весь вопрос, когда отвечаете на них. «Наилучшим вариантом с точки зрения использования ресурсов» является случай 3, учитывая, что использование вашей памяти будет довольно низким и что большинство платформ баз данных в любом случае будут обрабатывать метрические кол-во запросов в секунду.

2 голосов
/ 12 июля 2011

«Неверный» кажется неправильным ответом.

Существует ряд компромиссов, и «правильный» ответ зависит от факторов, которые вы не перечислили, таких как: 1) Это производственная база данных?2) Работает ли сайт онлайн, когда вы вставляете эти данные?3) Это нормально, если строка 1 вставлена ​​и видима для публики, а строка 10 985 - нет?4) Пишут ли другие за столом, пока вы?

Предполагая, что ответ на все эти вопросы - да, я бы, вероятно, по очереди прочитал и вставил строку.Первые два заблокируют ваш стол, чтобы никто другой не смог получить к нему доступ.С опцией 3 вы можете даже измерить вашу скорость вставок.

0 голосов
/ 12 июля 2011

Я думаю, что способ PHP предполагает вариант 3, потому что вы минимизируете объем используемой памяти. Это медленно, но уменьшает потребление памяти каждой операцией. Загрузка всего этого в один большой многомерный массив и выполнение сложной вставки требует гораздо больше ресурсов, и ускорение не намного лучше. Вопрос предполагает, что это долгосрочное задание, так что, возможно, именно это вас и сбило с толку.

Тот, кто написал это, похоже, не считал, что операции вставки дороги для загрузки данных и не предназначены для использования, когда у вас много данных для загрузки.

...