Недавно я беседовал с группой фанатов по вопросу: метод записи базы данных и максимальное количество строк данных, которые можно записать. После некоторых поисков и запросов в Интернете выяснилось, что предел вставки одной таблицы MySQL составляет от 30 000 до 5 000 000.
Во время встречи все также говорили о нескольких методах написания. Среди них один метод нестрессового тестирования является самым мощным среди доступной информации. Говорят, что производительность более чем в 20 раз выше, чем при написании программ, а именно загрузка данных. .
Оператор MySQL LOAD DATA — это команда, используемая для эффективного импорта больших объемов данных в таблицу базы данных. Он считывает данные из обычного текстового файла (обычно файла CSV) и массово вставляет их в указанную таблицу базы данных. Этот метод более эффективен, чем вставка построчно, и особенно подходит для импорта больших наборов данных.
Сценарии использования следующие:
Этот метод взлома временно не включен в рамки данного эксперимента. В основном он не позволяет использовать метод испытания под давлением для контроля давления и не подходит для написания тестирования производительности.
Ниже я перечисляю некоторые распространенные из них. MySQL
режим записи и просто проверьте производительность записи. В этой статье рассматривается только однопоточное решение, что касается производительности.
Сначала создайте службу MySQL локально с параметрами по умолчанию и без оптимизации. Затем создайте таблицу. Инструкция создания таблицы выглядит следующим образом:
CREATE TABLE `user` (
`id` int NOT NULL AUTO_INCREMENT COMMENT 'ID пользователя',
`name` varchar(32) DEFAULT 'FunTester' COMMENT 'имя пользователя',
`age` int NOT NULL COMMENT «Возраст пользователя»,
`level` int DEFAULT NULL COMMENT «Уровень пользователя»,
`region` varchar(32) DEFAULT «Супермаркет Сяоба» COMMENT «Регион пользователя»,
`address` varchar(512) DEFAULT NULL COMMENT «Адрес пользователя»,
`create_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=31 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
Второй метод тестирования заключается в использовании операторов MySQL для подсчета количества строк, записываемых в секунду. Посмотрите на максимальное количество операций записи в секунду.
SELECT COUNT(*),create_time FROM user group by create_time;
После каждого теста очищайте стол:
TRUNCATE TABLE user;
Подключитесь к службе MySQL с помощью JDBC.,Затем используйте однопоточный цикл пока для записи данных в базу данных. Это должен быть самый распространенный и простой способ.,Теоретически это худший способ сделать это.,Хотя я использую предварительный Функции скомпилированного,Но на самом деле это также повышает производительность клиента.,Это не влияет на производительность серверной части.
Сценарий следующий:
package com.funtest.mysql
import com.funtester.db.mysql.FunMySql
import com.funtester.frame.SourceCode
import com.funtester.utils.StringUtil
/**
* проходить JDBC К MySQL база данныхписатьданные */
class MysqlWriteWhile extends SourceCode {
public static void main(String[] args) {
String sqlFormat = "insert into user (name, age, level, region, address) values (?, ?, ?, ?, ?)";
String ipPort = "127.0.0.1:3306";// Адрес сервера
String database = "funtester"// Адрес сервера
String user = "root";// имя пользователя
String password = "funtester";// пароль
def base = new FunMySql(ipPort, database, user, password);// создать базу базовый класс данныхоперации
def preparedStatement = base.connection.prepareStatement(sqlFormat);// предварительно скомпилированный SQL заявление
while (true) {
String name = StringUtil.getString(16);// Случайно генерировать имена
int age = getRandomInt(100);// случайно сгенерированный возраст
int level = getRandomInt(10);// Случайно генерируемые уровни
String region = StringUtil.getString(32);// Случайно генерируемые области
String address = StringUtil.getString(512);// Случайно сгенерировать адрес
preparedStatement.setString(1, name);// Установить параметры
preparedStatement.setInt(2, age);// Установить параметры
preparedStatement.setInt(3, level);// Установить параметры
preparedStatement.setString(4, region);// Установить параметры
preparedStatement.setString(5, address);// Установить параметры
preparedStatement.executeUpdate();// Выполнить заявление вставки
}
preparedStatement.close();// закрыть ресурс
base.close();// закрыть ресурс
}
}
Результаты испытаний следующие:
количество строк | минута | Второй |
---|---|---|
6374 | 12 | 0 |
6197 | 12 | 1 |
6156 | 12 | 2 |
6176 | 12 | 3 |
6332 | 12 | 4 |
6545 | 12 | 5 |
7088 | 12 | 6 |
7309 | 12 | 7 |
7408 | 12 | 8 |
6099 | 12 | 9 |
Кажется, 7к больше, что намного лучше моего предыдущего результата. |
Я сначала тоже подумал Пакетная обработка JDBCЕго также можно значительно улучшитьпроизводительностьиз,Если у вас такая же идея, друзья,Хорошо, не волнуйся сейчас,Итак, давайте сначала посмотрим на тестовую программу.
package com.funtest.mysql
import com.funtester.db.mysql.FunMySql
import com.funtester.frame.SourceCode
import com.funtester.utils.StringUtil
/**
* проходить JDBC К MySQL база данныхписатьданные
*/
class MysqlWriteBatch extends SourceCode {
public static void main(String[] args) {
String sqlFormat = "insert into user (name, age, level, region, address) values (?, ?, ?, ?, ?)";
String ipPort = "127.0.0.1:3306";// Адрес сервера
String database = "funtester"// Адрес сервера
String user = "root";// имя пользователя
String password = "funtester";// пароль
def base = new FunMySql(ipPort, database, user, password);// создать базу базовый класс данныхоперации
def preparedStatement = base.connection.prepareStatement(sqlFormat);// предварительно скомпилированный SQL заявление
while (true) {
for (int j = 0; j < 10; j++) {
String name = StringUtil.getString(16);// Случайно генерировать имена
int age = getRandomInt(100);// случайно сгенерированный возраст
int level = getRandomInt(10);// Случайно генерируемые уровни
String region = StringUtil.getString(32);// Случайно генерируемые области
String address = StringUtil.getString(512);// Случайно сгенерировать адрес
preparedStatement.setString(1, name);// Установить параметры
preparedStatement.setInt(2, age);// Установить параметры
preparedStatement.setInt(3, level);// Установить параметры
preparedStatement.setString(4, region);// Установить параметры
preparedStatement.setString(5, address);// Установить параметры
preparedStatement.addBatch();// Добавить в пакет
}
preparedStatement.executeBatch();// Пакетное выполнение
}
preparedStatement.close();// закрыть ресурс
base.close();// закрыть ресурс
}
}
Результаты испытаний следующие:
количество строк | минута | Второй |
---|---|---|
7308 | 27 | 17 |
6817 | 27 | 18 |
6871 | 27 | 19 |
6367 | 27 | 20 |
6631 | 27 | 21 |
7310 | 27 | 22 |
6903 | 27 | 23 |
7258 | 27 | 24 |
7180 | 27 | 25 |
7309 | 27 | 26 |
7208 | 27 | 27 |
6640 | 27 | 28 |
Результат аналогичен циклу while. Позвольте мне поделиться результатами информации, которую я нашел ниже. Пакетная обработка просто снижает эффективность отправки данных туда и обратно на сервер, не более того. В фактической обработке операций MySQL сервером особых улучшений нет. |
здесьиз Инструкции по пакетной вставкеиз Это одинMySQLзаявление ВключатьNХОРОШОMySQLданные,Это не то же самое, что пакетная обработка. Пакетная обработка заключается в одновременной отправке множества элементов MySQL на сервер.,и Вставить несколько строка MySQL Вставить Nколичество строкв соответствии с。
Вот тестовый скрипт:
package com.funtest.mysql
import com.funtester.db.mysql.FunMySql
import com.funtester.frame.SourceCode
import com.funtester.utils.StringUtil
/**
* проходить JDBC К MySQL база данныхписатьданные */
class MysqlWriteWhile extends SourceCode {
public static void main(String[] args) {
String sqlFormat = "insert into user (name, age, level, region, address) values (?, ?, ?, ?, ?)";
String ipPort = "127.0.0.1:3306";// Адрес сервера
String database = "funtester"// Адрес сервера
String user = "root";// имя пользователя
String password = "funtester";// пароль
def base = new FunMySql(ipPort, database, user, password);// создать базу базовый класс данныхоперации
def preparedStatement = base.connection.prepareStatement(sqlFormat);// предварительно скомпилированный SQL заявление
while (true) {
String name = StringUtil.getString(16);// Случайно генерировать имена
int age = getRandomInt(100);// случайно сгенерированный возраст
int level = getRandomInt(10);// Случайно генерируемые уровни
String region = StringUtil.getString(32);// Случайно генерируемые области
String address = StringUtil.getString(512);// Случайно сгенерировать адрес
preparedStatement.setString(1, name);// Установить параметры
preparedStatement.setInt(2, age);// Установить параметры
preparedStatement.setInt(3, level);// Установить параметры
preparedStatement.setString(4, region);// Установить параметры
preparedStatement.setString(5, address);// Установить параметры
preparedStatement.executeUpdate();// Выполнить заявление вставки
}
preparedStatement.close();// закрыть ресурс
base.close();// закрыть ресурс
}
}
Результаты испытаний следующие:
количество строк | минута | Второй |
---|---|---|
12360 | 46 | 28 |
11460 | 46 | 29 |
14800 | 46 | 30 |
22110 | 46 | 31 |
23950 | 46 | 32 |
24750 | 46 | 33 |
24030 | 46 | 34 |
15230 | 46 | 35 |
12360 | 46 | 28 |
11460 | 46 | 29 |
14800 | 46 | 30 |
22110 | 46 | 31 |
Производительность улучшается, но очень нестабильно. Разница между самым высоким и самым низким в два раза больше. |
Однопоточный закончен. Я думаю, ты уже кое-что об этом знаешь,Фактически, расширение этих однопоточных методов до многопоточности стало функцией записи данных MySQL более высокого уровня. И после доступа к системе тестирования производительности,этотписатьколичество строка также станет более стабильной.