亚洲视频二区_亚洲欧洲日本天天堂在线观看_日韩一区二区在线观看_中文字幕不卡一区

公告:魔扣目錄網(wǎng)為廣大站長提供免費(fèi)收錄網(wǎng)站服務(wù),提交前請做好本站友鏈:【 網(wǎng)站目錄:http://www.430618.com 】, 免友鏈快審服務(wù)(50元/站),

點(diǎn)擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

 

最近做一個數(shù)據(jù)可視化項(xiàng)目時(shí),需要 Mock 大量的數(shù)據(jù)(千萬級)來進(jìn)行接口開發(fā)。本文將記錄探索實(shí)踐的全部過程。

1. 如何快速 Mock 大量數(shù)據(jù)

1.1 逐條插入數(shù)據(jù)

因?yàn)椴┲髦鳂I(yè)是搞前端開發(fā)的,對 MySQL 其實(shí)不是特別在行了。要 Mock 數(shù)據(jù),第一想法當(dāng)然是寫個程序或腳本來自動插入數(shù)據(jù)了。于是說干就干,很快一個基于 NodeJs 的 demo 就完成了。

建表 sql(為了演示方便,這里僅取4個字段,原測試 demo 有 21 個字段):

use test;
CREATE TABLE test.data (
 `id` INT NOT NULL,
 `nt` VARCHAR(100) NOT NULL,
 `imei` VARCHAR(100) NOT NULL,
 `model` VARCHAR(50) NOT NULL,
 PRIMARY KEY (id)
)

逐條插入數(shù)據(jù)代碼:

let mysql = require('mysql');
const uuidv1 = require('uuid/v1');
let connection = mysql.createConnection({
 host: 'localhost',
 port: '6666',
 user: 'root',
 password: '123456',
 database: 'test'
});
const close = () => connection.end();
function network() {
 return ['"wifi"', '"g4"', '"g3"', '"g2"'][Math.floor(Math.random() * 4)]
}
function phone_model() {
 return ['"NEX"','"x23"','"x21"','"x20"'][Math.floor(Math.random() * 4)]
}
function imei() {
 return `"${uuidv1()}"`;
}
connection.connect();
let s = Date.now();
let i = 0;
function insert() {
 connection.query(`insert into data(id, nt, imei, model) values (${i}, ${network()}, ${imei()}, ${phone_model()})`,
 function (error, results, fields) {
 if (error) throw error;
 if (i + 1 < 100000) {
 i++;
 insert();
 } else {
 console.log('done:' + (Date.now() - s));
 }
 });
}
insert();

用 10 條數(shù)據(jù)測試了下,perfect!完美工作。清空表,數(shù)量加大到1萬條數(shù)據(jù)測試,勉強(qiáng) perfect ,這次插入1萬數(shù)據(jù)耗時(shí)48192ms,也就是48s左右,還能勉強(qiáng)接受。

繼續(xù)擴(kuò)量到10萬條數(shù)據(jù),這下就尷尬的很明顯了,生成10萬條數(shù)據(jù),一共耗時(shí)618983ms,618s,也就是10分鐘左右。大概心里估計(jì)了下,就算以線性遞增來算,那么100萬條數(shù)據(jù)大概就是100分鐘,1000萬數(shù)據(jù)大概是1000分鐘,也就是近17個小時(shí)。

很明顯,這效率太慢了,必須尋找效率更高的方式。

1.2 使用儲存過程批量插入數(shù)據(jù)

在網(wǎng)上搜索了一會兒,果然找到了一種新方式:使用 mysql 儲存過程來批量插入數(shù)據(jù)。所謂“儲存過程”,個人認(rèn)為就是批處理。

建表 sql,因?yàn)閿?shù)據(jù)量大,這里加上了分區(qū):

use test;
CREATE TABLE test.data (
 `id` INT NOT NULL,
 `nt` VARCHAR(100) NOT NULL,
 `imei` VARCHAR(100) NOT NULL,
 `model` VARCHAR(50) NOT NULL,
 PRIMARY KEY (id)
) ENGINE = MyISAM ROW_FORMAT = DEFAULT
 partition BY RANGE (id) (
 partition p0 VALUES LESS THAN (10000000),
 partition p1 VALUES LESS THAN (20000000),
 partition p2 VALUES LESS THAN (30000000),
 partition p3 VALUES LESS THAN (40000000),
 partition p4 VALUES LESS THAN (50000000),
 partition p5 VALUES LESS THAN (60000000),
 partition p6 VALUES LESS THAN (70000000),
 partition p7 VALUES LESS THAN (80000000),
 partition p8 VALUES LESS THAN (90000000),
 Partition p9 VALUES LESS THAN MAXVALUE
 );

接著是創(chuàng)建 mysql 儲存過程,不過在編寫儲存過程代碼時(shí),遇到了一個問題,如何實(shí)現(xiàn)下面函數(shù)的功能,即隨機(jī)從 wigi, 4g, 3g, 2g 中返回一個網(wǎng)絡(luò)類型。

function network() {
 return ['"wifi"', '"g4"', '"g3"', '"g2"'][Math.floor(Math.random() * 4)]
}

2. 如何在儲存過程中基于數(shù)組來生成隨機(jī)值

查了大量資料,發(fā)現(xiàn) mysql 儲存過程不支持?jǐn)?shù)組操作。一時(shí)間,似乎走到了死胡同。最后發(fā)現(xiàn)了這篇文章:MySQL函數(shù)和存儲過程生成電話號碼。作者生成電話號碼的思路給了我啟發(fā),于是我參照他的思路,實(shí)現(xiàn)了隨機(jī)生成網(wǎng)絡(luò)類型的功能。

----------------------------
-- 生成網(wǎng)絡(luò)類型的函數(shù)
----------------------------
DELIMITER $$
create function network() returns char(4)
begin 
 declare networks varchar(100) default "wifi4g 3g 2g "; -- 1,5,9,13
 declare idx int;
 declare ret char(4);
 set idx = 1+floor(rand()*4)*4;
 set ret = trim(substring(networks,idx,4));
 return ret;
end $$
DELIMITER ;

大概思路就是:

  • 找出數(shù)組中最長的字符串項(xiàng),比如 wifi,4g,3g,2g 中最長的項(xiàng)是 'wifi',長度為4
  • 將數(shù)組所有項(xiàng)用空格填充,讓其與最長項(xiàng)長度一樣,即wifi4g 3g 2g
  • 隨機(jī)生成固定的字符截取起始點(diǎn)。這里的隨機(jī),固定可能會不太好理解。看這個表達(dá)式1+floor(rand()*4)*4就清楚了,此表達(dá)式總是返回 1,5,9,13中某個值
  • 截取字符串,同時(shí)去掉填充的空格,trim(substring(networks,idx,4)),就得到隨機(jī)值了

解決隨機(jī)生成值的問題后,儲存過程的代碼也就出來了:

----------------------------
-- 生成網(wǎng)絡(luò)類型的函數(shù)
----------------------------
DELIMITER $$
create function network() returns char(4)
begin 
 declare networks varchar(100) default "wifi4g 3g 2g "; -- 1,5,9,13
 declare idx int;
 declare ret char(4);
 set idx = 1+floor(rand()*4)*4;
 set ret = trim(substring(networks,idx,4));
 return ret;
end $$
DELIMITER ;
----------------------------
-- 生成機(jī)型的函數(shù)
----------------------------
DELIMITER $$
create function phone_model() returns char(10)
begin 
 declare phone_types varchar(100) default "NEX x23 x21 x20 x9 x7 x6 x5 Z1 Z2 Z3 Y97 Y91 Y85 Y83 Y81 Y79 ";
 declare idx int;
 declare ret char(10);
 set idx = 1+floor(rand()*17)*4;
 set ret = trim(substring(phone_types,idx,4));
 return ret;
end $$
DELIMITER ;
----------------------------
-- 生成IMEI的函數(shù)
----------------------------
DELIMITER $$
create function randchar() returns char(5)
begin
 declare ret char(5); 
 set ret = substring("ABCDEFGHIJKLMNOPQRSTUVWXYZ",floor(1+26*rand()),1);
 return ret;
end $$
DELIMITER ;
DELIMITER $$
create function imei() returns char(50)
begin
 declare ret char(50) default ""; 
 declare imeiLen int default 11;
 DECLARE idx INT default 0;
 WHILE idx < imeiLen DO
 SET idx = idx + 1;
 SET ret = CONCAT(ret, randchar());
 END WHILE;
 return ret;
end $$
DELIMITER ;
----------------------------
-- 創(chuàng)建儲存過程
----------------------------
use test;
DROP PROCEDURE IF EXISTS test.BatchInsertCustomer;
delimiter //
CREATE PROCEDURE BatchInsertCustomer(IN start INT,IN loop_time INT)
 BEGIN
 DECLARE Var INT;
 DECLARE ID INT;
 SET Var = 0;
 SET ID= start;
 WHILE Var < loop_time DO
 insert into data(`id`, `nt`, `imei`, `model`) 
 values (ID, network(), imei(), phone_model());
 SET Var = Var + 1;
 SET ID = ID + 1;
 END WHILE;
 END;
 //
delimiter ;

調(diào)用儲存過程:

-- 調(diào)用
ALTER TABLE test DISABLE KEYS;
CALL BatchInsertCustomer(1, 10);
ALTER TABLE test ENABLE KEYS;

在測試時(shí),使用儲存過程生成1000萬數(shù)據(jù)大概是140分鐘,不到2個半小時(shí)。相比逐條插入的17個小時(shí),快了8,9倍,效率提升不少。

3. 小結(jié)

使用 mysql 儲存過程可以快速地生成 Mock 數(shù)據(jù)。同時(shí)本文還提供了一種“如何在儲存過程中基于數(shù)組來生成隨機(jī)值“的思路,希望對大家有些幫助。

3.1 參考

  • MySQL批量插入大量數(shù)據(jù)方法
  • MySQL函數(shù)和存儲過程生成電話號碼

分享到:
標(biāo)簽:性能測試 mysql
用戶無頭像

網(wǎng)友整理

注冊時(shí)間:

網(wǎng)站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨(dú)大挑戰(zhàn)2018-06-03

數(shù)獨(dú)一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學(xué)四六

運(yùn)動步數(shù)有氧達(dá)人2018-06-03

記錄運(yùn)動步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績評定2018-06-03

通用課目體育訓(xùn)練成績評定