LOAD DATA LOCAL INFILE - заливка файлов в MySQL

BAZAg

Client
Регистрация
08.11.2015
Сообщения
2 375
Реакции
2 782
Баллы
113
Пол дня трепало мой мозг...
Но, все же получилось!

Собственно в чём сама проблема?
Данные в MySQL можно заливать с файла используя LOAD DATA LOCAL INFILE.
Тоесть, готовим файл:
Код:
Развернуть Свернуть Копировать
"7b7a53e239400a13bd6be6c91c4f6c4e","2020","0","0","123456"
"3a824154b16ed7dab899bf000b80eeee","2022","0","0","123456"
"051928341be67dcba03f0e04104d9047","2048","0","0","123456"
Сохраняем его в условный temp.csv
C#:
Развернуть Свернуть Копировать
string path = Path.Combine(project.Directory, "temp.csv");
var dic1 = new System.Collections.Specialized.OrderedDictionary{{ "file", path}}; // используя параметр не нужно будет делать path.Replace("\\", "/");
Готовим запрос:
SQL:
Развернуть Свернуть Копировать
LOAD DATA LOCAL INFILE @file
 INTO TABLE `names_buffer`
 FIELDS TERMINATED BY ','
 ENCLOSED BY '""'
 LINES TERMINATED BY '\r\n'
 (`hash`, `domain`, `state`, `status`, `ts`);

C#:
Развернуть Свернуть Копировать
string text_out = ZennoPoster.Db.ExecuteQuery(sql, dic1 , ZennoLab.InterfacesLibrary.Enums.Db.DbProvider.MySqlClient, connect_db, "^^^", "|||").Trim();

И за задумкой все должно работать.
Но нет, так не работает...

Сначала ругается что-то там типа доступ запрещен.
AI рассказывает что нужно дать права FILE
GRANT FILE ON *.* TO 'username'@'%';
FLUSH PRIVILEGES;
Выдал их, но, потом все же пришлось выдавать права супер пользователя:
GRANT SUPER ON *.* TO 'username'@'%';
FLUSH PRIVILEGES;

Потом должно показать здесь ON: SHOW GLOBAL VARIABLES LIKE 'local_infile';
Установка примерно так: SET GLOBAL local_infile = 1;

И вот, права есть, настройка включена, а файл не грузится.
Оказалось, в строке подключения нужно указать параметр:
AllowLoadLocalInfile=true

Думал, что уже всё - поедет.
Нет, не едет...
Оказывается, что для того, чтобы можно было отправлять большие файлы - ещё окно увеличить нужно:
SET GLOBAL max_allowed_packet = 1073741824;
Увеличил (так вот его без супер пользовтеля увеличить не получается - из-за чего и пришлось супер пользователя давать).

Думал уже заработает. Нет, не заработало. Точнее заработало - половину файла грузит и падает по ошибке.
Оказалось, что нужно еще в строке подключения указать сколько времени ждать ответа от базы.
DefaultCommandTimeout=300 (поставил 5 минут)

И уже тогда поехало как нужно - 1 млн строчек залетает за 1 минуту примерно.
Строка подключения такая получилась:

C#:
Развернуть Свернуть Копировать
var dic = new Dictionary<string,string>();
dic["server"] = "8.8.8.8";
dic["user id"] = "username";
dic["password"] = "pass";
dic["database"] = "dbname";
dic["persistsecurityinfo"] = "True";

dic["allowuservariables"] = "True"; // пользовательские переменные начинающиеся с @
dic["pooling"] = "false"; // не держать соединение
dic["AllowLoadLocalInfile"] = "true"; // Разрешает LOAD DATA LOCAL INFILE
dic["DefaultCommandTimeout"] = "300"; // Время ожидания (в секундах) выполнения любого SQL-запроса.
string connect_db = string.Join(";",dic.Select(x=>string.Join("=", new[]{x.Key,x.Value})));

Подготовка файла:
C#:
Развернуть Свернуть Копировать
string path = Path.Combine(project.Directory, "temp.csv");
var csvLines = subChunk.AsParallel().Select(x => {
    string hash = x.GetMD5Hash();
    string ts = "123456";
    return $"\"{hash}\",\"{x}\",\"0\",\"0\",\"{ts}\"";
});
File.WriteAllLines(path, csvLines);
Сам запрос:
C#:
Развернуть Свернуть Копировать
string sql = @"
                    SET GLOBAL max_allowed_packet = 1073741824;

                    CREATE TABLE IF NOT EXISTS `names_buffer` (
                        `hash` VARCHAR(32) NOT NULL PRIMARY KEY,
                        `domain` VARCHAR(255) NOT NULL,
                        `state` INT DEFAULT 0,
                        `status` INT DEFAULT 0,
                        `ts` INT DEFAULT 0
                    ) ENGINE=InnoDB;
                    TRUNCATE TABLE `names_buffer`;
                    LOAD DATA LOCAL INFILE @file
                    INTO TABLE `names_buffer`
                    FIELDS TERMINATED BY ','
                    ENCLOSED BY '""'
                    LINES TERMINATED BY '\r\n'
                    (`hash`, `domain`, `state`, `status`, `ts`);
                    INSERT INTO `names` (`hash`, `domain`, `state`, `status`, `ts`)
                    SELECT b.`hash`, b.`domain`, b.`state`, b.`status`, b.`ts`
                    FROM `names_buffer` b
                    LEFT JOIN `names` target ON b.`hash` = target.`hash`
                    WHERE target.`hash` IS NULL;
                    TRUNCATE TABLE `names_buffer`;
                    SET GLOBAL max_allowed_packet = 4194304;
                    ";

C#:
Развернуть Свернуть Копировать
return ZennoPoster.Db.ExecuteQuery(sql, dic1 , ZennoLab.InterfacesLibrary.Enums.Db.DbProvider.MySqlClient, connect_db, "^^^", "|||").Trim();

А люди говорят вот, AI все проблемы решает...
Так вот не особо решает - то одну ересь пишет, то другую, то третью - а время то тикает...

Сюда выложил - может AI обучится и лучше будет рекомендовать ответы :)
 
А люди говорят вот, AI все проблемы решает...
Так вот не особо решает - то одну ересь пишет, то другую, то третью - а время то тикает...
Так называемый "AI", а точнее нейронка - достаточно ограниченный инструмент (именно инструмент).

То, что он "знает" сейчас, а следовательно и предлагает - посредственно (дороговато нейроны задействовать, ещё и дорогими путями) + устарело (давно обучали), активный же поиск урезан у большинства (жрёт ресурсы - необходимо поднимать браузеры), кроме м.б. ChatGPT
и нередко собирает мусор, так как нейронка лишь запрашивает поиск, а там как "повезёт".

Уровень проблемы:

shit.png

Глупо пенять на инструмент, особенно юзая кем-то подготовленные (пусть даже официально) за копеешные тарифы или тем более бесплатно..
 
Последнее редактирование:
ак называемый "AI", а точнее нейронка - достаточно ограниченный инструмент (именно инструмент).
Верно!
Только у меня болезненный опыт - алергия на совет обратись к AI.
Что-то из разряда: Так загугли, поищи и тп.

Особенно когда уже использовал нейронку, гуглил, искал.
Ничего не получилось, начинаешь разбираться в тонкостях работы и идешь на условный форум к людям.
Потом говоришь условному заказчику/пользователям на форуме/жене о проблеме.
И первый ответ который получаешь:
- А ты что не можешь спросить у GPT что ли?
- Так посоветуйся в AI, он поможет!
Что всегда (в много много случаев) выглядит не уместно...
 
когда уже использовал нейронку, гуглил, искал
Берётся всё что можно достать (исходный код, декомпил, логи) и натравливается на разные, но топовые нейронки.
В ином случае это глупая потеря значительного времени и нервов.

Но опять же, зависит от ситуации и уместности.

Но по итогу: опыт + нейронки + своё окружение и свои утилиты... Необходимо, несмотря на всю смесь "крутизны и убожества" одного лишь, но крайне значительного инструмента.
 
Последнее редактирование:
Берётся всё что можно достать (исходный код, декомпил, логи) и натравливается на разные, но топовые нейронки.
В ином случае это глупая потеря значительного времени и нервов.

Но опять же, зависит от ситуации и уместности.
Когда есть знания как это автоматизировать, формировать эти пакеты автоматически - то годится такой подход.
Если не знаешь, и приходится проворачивать это руками итеративно - то времени будет затрачено больше чем просто сделать решение.
Может быть действительно большинство людей уже все изучило и автоматизировало и AI по первому чиху выдает сразу готовый результат.

Мой же путь больше похож на:
опыт + нейронки + своё окружение и утилиты...

Необходимо, несмотря на всю смесь "крутизны и убожества" одного лишь, но крайне значительного инструмента.
То что Вы смотрите на стакан сверху и видите круг совершенно не значит, что я не могу на него смотреть сбоку и видеть прямоугольник.
Другими словами, то что Вы в чём-то умнее/компетентнее совершенно не делает меня безмозглым.
 
Может быть действительно большинство людей уже все изучило и автоматизировало
А при чём тут какое-то "большинство" и что вам до него?
С большинством как всегда всё плохо (и хорошо тем, кто на этом зарабатывает).
Может быть ... AI по первому чиху выдает сразу готовый результат.
Пока лишь можно нивелировать недостатки, что тоже объёмная работа.
То что Вы смотрите на стакан сверху и видите круг совершенно не значит, что я не могу на него смотреть сбоку и видеть прямоугольник.
Я предпочитаю не смотреть на стакан.
Другими словами, то что Вы в чём-то умнее/компетентнее совершенно не делает меня безмозглым.
Мы тут все в какой-то мере безмозглые.
 
  • Оценить
Реакции: BAZAg
А при чём тут какое-то "большинство" и что вам до него?
С большинством как всегда всё плохо (и хорошо тем, кто на этом зарабатывает).

Пока лишь можно нивелировать недостатки, что тоже объёмная работа.

Я предпочитаю не смотреть на стакан.

Мы тут все в какой-то мере безмозглые.
А есть может что добавить по теме топика?
Я же знаю, что Вы отлично технически подкованы...

Начал заливать файлы по 1млн строчек - и привет-привет - SSD диски работают на пределе.
В ОЗУ заливать 350млн строчек базы - не реалистично выглядит (не обладаю такими ресурсами).
Тоесть, хотя и получилось технически иметь возможность заливать данные в базу в нужных объемах - всеравно есть проблема с тем, что обработка происходит долговато...

AI говорит о том, что все, я упёрся в потолок производительности.
Но, я же понимаю, что это не верно...
Банально отрезав зону от имени - объем данных существенно уменьшился.
Думаю ещё подобные оптимизации нужны...
 
А есть может что добавить по теме топика?
Я же знаю, что Вы отлично технически подкованы...

Начал заливать файлы по 1млн строчек - и привет-привет - SSD диски работают на пределе.
В ОЗУ заливать 350млн строчек базы - не реалистично выглядит (не обладаю такими ресурсами).
Тоесть, хотя и получилось технически иметь возможность заливать данные в базу в нужных объемах - всеравно есть проблема с тем, что обработка происходит долговато...

AI говорит о том, что все, я упёрся в потолок производительности.
Но, я же понимаю, что это не верно...
Банально отрезав зону от имени - объем данных существенно уменьшился.
Думаю ещё подобные оптимизации нужны...
По умолчанию, настройки у баз достаточно убогие (например, как для микроволновок у оригинального PostgreSQL).
Данные неплохо бы сократить/сжать, но...

Лучше было бы вспомнить про первопричину: какова стоимость одной или тысячи строчек - стоит ли оно вообще того или это какой-то мусор.
 
  • Оценить
Реакции: BAZAg
По умолчанию, настройки у баз достаточно убогие (например, как для микроволновок у оригинального PostgreSQL).
Данные неплохо бы сократить/сжать, но...

Лучше было бы вспомнить про первопричину: какова стоимость одной или тысячи строчек - стоит ли оно вообще того или это какой-то мусор.
Задача из разряда вот таких: тут = $100, или тут = $80 в месяц, или таких или таких.
Или то что было бесплатно ищется на форуме по ICANN тут или тут.
Собственно это продолжение истории о которой говорил здесь.

Если совсем кратко - то хочу разобраться с тем, как держать актуальную базу данных о всех доменах.
Терять данные не вариант... А ускорять надо, в идеале не разнося схему на большое количество серверов (это также усложнит всю обработку когда данные будут в больших объемах гоняться туда-сюда).
Естественно в процессе попадаю на технические ограничения.
С AI консультируюсь, гуглю.

Но... Не хватает информации от тех, кто уже имеет какой-то опыт.
Вместо помощи - отправляют к AI или фриланс/рекламный раздел.
 

Вместо бесконечных оптимизаций, иногда проще сменить технологию...
---
Дата: 2026-08-27 20:54:42 MSK
Среда: Windows / Go 1.25 / ClickHouse 24.3 (Native Protocol, LZ4)

1. Основные результаты​

Бенчмарк измеряет производительность парсинга и загрузки доменных списков из W:\ListsData\HostData в ClickHouse. Пайплайн: потоковое чтение, нормализация (IDN/Punycode, RFC 1035), извлечение TLD, параллельная вставка через native TCP.
Ключевые метрики:
  • Парсер: до 7,015,256 доменов/сек (стриминг + нормализация + TLD)
  • ClickHouse: до 2,851,743 строк/сек (Domains)
  • Память: 50–120 МБ даже при десятках миллионов записей
  • Сжатие: 2.8x – 4.5x (LZ4, ReplacingMergeTree + LowCardinality(String))

2. Результаты по датасетам​

Датасет / ФорматРазмерСтрокВремяПарсинг (дом/с)CH (строк/с)Диск (МБ/с)Avg/P95 (мс)
Tranco Top Domains (TXT)77.8 МБ4.9M2.04с6.39M2.40M38.1158 / 181
Tranco Top Domains (CSV)114.2 МБ4.9M1.95с4.09M2.51M58.5150 / 178
Top 1M CMS (URL)36.4 МБ1M0.61с2.36M1.65M60.1136 / 154
Cloudflare Radar 1M (CSV)14.3 МБ1M0.37с6.18M2.72M38.5113 / 143
SimilarWeb Domains (TXT)13.3 МБ0.84M0.36с6.04M2.33M37.1132 / 168
deCloudflare Sharked (TXT)76.8 МБ4.71M1.65с7.02M2.85M46.5130 / 150
Active DNS A-Record (domain[IP])202.2 МБ6.13M2.40с3.65M2.55M84.1151 / 179
SimilarWeb Full (JSONL)2.55 ГБ0.84M1.04с41K0.81M2452130 / 145
Global Domains Master (TXT)4.26 ГБ10M3.81с5.29M2.62M1117149 / 178

3. Конкурентность и размер батча​

Тест на 300K доменов (tranco_7PL5X_domains.txt):
WorkersBatchСкорость (строк/с)ВремяAvg/P95 (мс)Память (МБ)
110K467K642мс21 / 2454
125K535K560мс46 / 5142
150K522K574мс94 / 12165
1100K442K679мс221 / 226119
210K926K324мс21 / 24121
225K981K306мс49 / 5779
250K827K363мс115 / 121129
2100K592K506мс252 / 268172
410K1.50M199мс25 / 30100
425K1.66M181мс55 / 6166
450K1.26M238мс111 / 126135
4100K973K308мс262 / 277197
810K2.34M128мс28 / 3770
825K2.32M129мс60 / 76136
850K1.79M167мс117 / 123139
8100K1.03M290мс248 / 256200
1610K2.33M129мс47 / 86147
1625K2.19M137мс69 / 90152
1650K1.77M170мс122 / 131132
16100K1.12M267мс221 / 223253
Оптимум: 8 workers × 10–25K батч = 2.3M строк/сек при <140 МБ памяти.

4. Сжатие в ClickHouse​

ДатасетСтрокRAW (МБ)On-Disk (МБ)LZ4Parts
Tranco TXT4.9M17354.63.17x34
Tranco CSV4.9M17354.03.21x29
Top 1M CMS0.99M3512.22.86x15
Cloudflare 1M1M34.511.13.11x21
SimilarWeb TXT0.84M30.211.62.61x17
deCloudflare4.71M16845.43.70x29
Active DNS A6.13M22061.63.57x26
SimilarWeb JSONL0.84M30.310.82.82x12
Global Master10M35995.33.77x40

 
  • Оценить
Реакции: BAZAg

Кто просматривает тему: (Всего: 2, Пользователи: 0, Гости: 2)