2015-08-31 2 views
1

Я ищу наилучшие способы достижения большого обновления данных/вставки в SQL. В моем конкретном случае используется MySQL 5.6, но теоретически версия SQL не так важна.Ищите лучшую практику/Самый эффективный большой SQL UPDATE/INSERT

Я загружаю большой файл CSV, заполненный данными, которые мне нужно сбрасывать в таблицу MySQL. Мое приложение анализирует CSV и готовится к вставке в базу данных.

Мне нужна таблица, которая будет точной копией данных (CSV), которая приходит каждый раз, а не добавляется каждый раз до конца. Я ищу лучший способ добиться этого.

К моим текущим возможностям SQL я подумал, что лучше всего просто обрезать таблицу каждый раз и заполнить ее данными по мере ее поступления, но я теперь не уверен, что это лучше, чем индексирование столбца, и используя INSERT ... ON DUPLICATE KEY ,

Мой вопрос/с являются следующие:

  • это лучше укоротить, а затем вставить данные в пустую таблицу, или лучше найти различия данных и использовать INSERT .. ON DUPLICATE KEY обновить только строки, в которых приложение обнаружило несоответствие данных

  • В любом случае после этого лучше всего отформатировать отдельный SQL-запрос UPDATE/INSERT запросов на строку данных и отправить их на сервер. Или лучше отформатировать очень большой запрос со всеми данными в нем или, возможно, разбить этот более крупный запрос на нечто более управляемое, чтобы не позволить серверу тайм-аут.

В таблице, которая проходит, имеется приблизительно 100 тыс. Строк. В настоящее время я обрезаю таблицу перед запуском любых INSERT. Затем я разбил строки на 10 разных наборов и выполнил 10 больших INSERT запросов к базе данных. Моя единственная забота заключается в том, что я недостаточно разбираюсь в блокировке таблиц и не уверен в том, что разделение на самом деле достигает чего-то значительного.

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

DB Disk Writes

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

+1

Привет, я хотел бы предложить вам пойти с [SQLyog] (https://www.webyog.com/product/sqlyog), где вы можете импортировать либо «структуру и данные» или " данных "в формате .CSV в таблицу. Рекомендуется сначала импортировать структуру таблицы, а затем импортировать данные для эффективного импорта. Вы также можете указать куски данных, которые необходимо импортировать одновременно, чтобы избежать потери соединения. – Mathew

+0

Спасибо за предложение Мэтью. Я фактически уже использую Workbench MySQL, который имеет такую ​​же функциональность при импорте CSV в таблицу, но процедура должна быть автоматической и встроена в программу для конечных пользователей :) Все хорошо, Майкл ниже (отмечен как ответ) дал мне точно что мне нужно. Будьте внимательны и полезны для вас, хотя спасибо! –

ответ

1

Вы должны использовать LOAD DATA LOCAL INFILE вместо операций вставки/обновления, когда работаете с большими csv файлами. Вы не указали, какие операции синтаксического анализа вы выполняете перед вставкой, некоторые из них могут быть возможны только с LOAD DATA LOCAL INFILE. TRUNCATE таблица перед заявлением.

Вот пример для LOAD DATA LOCAL INFILE заявления, которое игнорирует первую строку (заголовок) и заменяет значения запятой для поля цены при загрузке данных, только в качестве примера:

LOAD DATA LOCAL INFILE 'file.csv' 
INTO TABLE table 
CHARACTER SET UTF8 
FIELDS TERMINATED BY '\t' 
ENCLOSED BY '\"' 
IGNORE 1 LINES 
(col1,col2,col3,colN, @price) 
SET price = REPLACE(@price,',','.'); 

Как вы сказали, что вы нужны все поля из CSV, просто передать имена столбца здесь

(col1,col2,col3,colN, @price) 

в том же порядке, как они находятся в вашем формате CSV. Это будет быстрее, чем любая вставка, которую вы могли бы написать.

Чтобы включить LOAD DATA LOCAL INFILE, вам необходимо установить флаг соединения при установлении соединения с базой данных (в пределах параметров непосредственно в параметрах подключения, после чего они не работают), например. с помощью PHP PDO:

$dbh = new PDO('mysql:host=' . env('DB_HOST') . ';dbname=' . $database, env('DB_USERNAME'), env('DB_PASSWORD'), 
       [PDO::MYSQL_ATTR_LOCAL_INFILE => 1]); 
+1

Это потрясающе спасибо Майкл, я попробую :) –

Смежные вопросы