Работа с большой БД.

LiMe

Client
Регистрация
10.12.2015
Сообщения
593
Благодарностей
314
Баллы
63
Парни, подскажите пожалуйста, есть огромная таблица с данными [~20-30млн.]: ID, Login. Беру логин и делаю проверку, вроде бы все замечательно, на большем объеме не вроде бы не каких проблем я не вижу, но как только данные в таблице заканчиваются, становится заметно, что он просто сжирает данные куда-то. Также об этом догадывался после определенных правок, что результат работы уменьшился в пару тройку раз.

Сейчас код который работает с БД выглядит вот так:
C#:
db.query("LOCK TABLES " + project.Variables["Table"].Value + " WRITE");

List<string> row = db.getRow("SELECT * FROM " + project.Variables["Table"].Value + " LIMIT " + project.Variables["RND"].Value + ", 1");
project.Variables["ID"].Value = row [0];
project.Variables["Login"].Value = row[1];

db.query("DELETE FROM " + project.Variables["Table"].Value + " WHERE ID = '" + project.Variables["ID"].Value + "'");

db.query("UNLOCK TABLES");
Отрабатывает он как надо быстро, но куда-то не понятно кушает данные. Попытался найти какие-то другие варианты взять случайное значение с таблицы, но увы все решения которые нашел, выполняются очень долго [~3-15 секунд], этот же вариант отрабатывает за 0,0031 секунды.

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

doc

Client
Регистрация
30.03.2012
Сообщения
8 605
Благодарностей
4 596
Баллы
113
Парни, подскажите пожалуйста, есть огромная таблица с данными [~20-30млн.]: ID, Login. Беру логин и делаю проверку, вроде бы все замечательно, на большем объеме не вроде бы не каких проблем я не вижу, но как только данные в таблице заканчиваются, становится заметно, что он просто сжирает данные куда-то. Также об этом догадывался после определенных правок, что результат работы уменьшился в пару тройку раз.

Сейчас код который работает с БД выглядит вот так:
C#:
db.query("LOCK TABLES " + project.Variables["Table"].Value + " WRITE");

List<string> row = db.getRow("SELECT * FROM " + project.Variables["Table"].Value + " LIMIT " + project.Variables["RND"].Value + ", 1");
project.Variables["ID"].Value = row [0];
project.Variables["Login"].Value = row[1];

db.query("DELETE FROM " + project.Variables["Table"].Value + " WHERE ID = '" + project.Variables["ID"].Value + "'");

db.query("UNLOCK TABLES");
Отрабатывает он как надо быстро, но куда-то не понятно кушает данные. Попытался найти какие-то другие варианты взять случайное значение с таблицы, но увы все решения которые нашел, выполняются очень долго [~3-15 секунд], этот же вариант отрабатывает за 0,0031 секунды.

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

LiMe

Client
Регистрация
10.12.2015
Сообщения
593
Благодарностей
314
Баллы
63

doc

Client
Регистрация
30.03.2012
Сообщения
8 605
Благодарностей
4 596
Баллы
113

WebBot

Client
Регистрация
04.04.2015
Сообщения
1 717
Благодарностей
1 375
Баллы
113
Это зенновские методы работы с бд?
Нет, это не зенновские, а из моего класса что я выкладывал в 4 конкурсе шаблонов - Заготовка для работы с БД MySQL в кубике C#

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

WebBot

Client
Регистрация
04.04.2015
Сообщения
1 717
Благодарностей
1 375
Баллы
113
И да, откуда у вас берется значение в переменной project.Variables["RND"].Value ? Оно должно получаться тут же путем подсчета строк в таблице на данный момент т.е SELECT COUNT(*) FROM таблица WHERE условия
Если же оно у вас просто генериться в некотором диапазоне, то такого смещения в таблице может просто не оказаться и строка не возьмется
вот тут есть пример с подсчетом строк в таблице, генериации случайного числа от 0 до этого кол-ва строк и подставновка в запрос
 

LiMe

Client
Регистрация
10.12.2015
Сообщения
593
Благодарностей
314
Баллы
63
была мысль, но не оправдалась. Пробовал воспроизвести тест на меньшем объёме, чтобы более детально рассмотреть потери?
Не проверял, надо пробовать.

Нет, это не зенновские, а из моего класса что я выкладывал в 4 конкурсе шаблонов - Заготовка для работы с БД MySQL в кубике C#

@LiMe что конкретно имеется ввиду под сжиранием данных как только данные в таблице заканчиваются? Если вы про размер файла базы, то да, он все так же будет большим ... или вы про что-то другое?
Да, ошибочка, извините, с вашей темы бралось. Имеется виду, что проект работает в 200 потоков, и при остатки в базе 20-30 тыс. логинов возникает проблема, обработка логинов не идет, а данные с таблицы куда-то пропадают.

И да, откуда у вас берется значение в переменной project.Variables["RND"].Value ? Оно должно получаться тут же путем подсчета строк в таблице на данный момент т.е SELECT COUNT(*) FROM таблица WHERE условия
Если же оно у вас просто генериться в некотором диапазоне, то такого смещения в таблице может просто не оказаться и строка не возьмется
вот тут есть пример с подсчетом строк в таблице, генериации случайного числа от 0 до этого кол-ва строк и подставновка в запрос
Да, там идет генерация в диапазоне пары тысяч, т.е. на сколько я понимаю в любом случае такая строка будет, но беда в том что, на большем количестве строк я не проверял, но на маленьком заметил что в один момент просто соржались 20к строк, по логу вижу что работа на проводилась не какая, а строк нет...
Попробую ваш вариант, надеюсь поможет.
 

WebBot

Client
Регистрация
04.04.2015
Сообщения
1 717
Благодарностей
1 375
Баллы
113
Если случайное число генериться в диапазоне "пары тысяч", то вышеописанная проблема может возникнуть только если строк в таблице как раз осталось меньше чем пара тысяч. Если логинов 20-30к, то такой ошибки быть не должно. Но в любом случае правильно - тут же получать точное количество строк и генерить число от 0 до этого количества. Тогда могу предположить что id/login берется нормально из БД и сразу же оттуда удаляется (как и сделано у вас в коде), но вот дальше в шаблоне идет какой-то затык/ошибка/недочет и действие не выполняется. Поток завершается так и не выполнив нужное действие, но обратно в БД логин не вернув. 200 таких потоков, которые не выполняют действия с логином, а просто берут его с удалением из БД и завершаются не выполнив задачу - очень быстро убьют 20-50к строк таблицы. Я бы на вашем месте проанализировал на ошибки ту часть шаблона, которая работает с уже взятым из БД логином ... вероятнее всего ошибка где-то там.
 

LiMe

Client
Регистрация
10.12.2015
Сообщения
593
Благодарностей
314
Баллы
63
Если случайное число генериться в диапазоне "пары тысяч", то вышеописанная проблема может возникнуть только если строк в таблице как раз осталось меньше чем пара тысяч. Если логинов 20-30к, то такой ошибки быть не должно. Но в любом случае правильно - тут же получать точное количество строк и генерить число от 0 до этого количества. Тогда могу предположить что id/login берется нормально из БД и сразу же оттуда удаляется (как и сделано у вас в коде), но вот дальше в шаблоне идет какой-то затык/ошибка/недочет и действие не выполняется. Поток завершается так и не выполнив нужное действие, но обратно в БД логин не вернув. 200 таких потоков, которые не выполняют действия с логином, а просто берут его с удалением из БД и завершаются не выполнив задачу - очень быстро убьют 20-50к строк таблицы. Я бы на вашем месте проанализировал на ошибки ту часть шаблона, которая работает с уже взятым из БД логином ... вероятнее всего ошибка где-то там.
Спасибо, наверное так и сделаю, попробую использовать ваш предложенный код, и полностью пересоберу шаблон, так как в какой-то момент результат работы уменьшился в разы, думал шаблон в этом не виноват, но как случилась ситуация с пропажей строк, позадумался и решил искать проблему.

@WebBot и @doc, спасибо что откликнулись.
 

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