最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

MYSQL讀寫性能測試的簡單記錄

 更新時間:2022年08月16日 10:00:12   作者:焱齒  
本文主要介紹了MYSQL讀寫性能測試的簡單記錄,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

進行測試之前首先保證你已經(jīng)可以對數(shù)據(jù)庫進行讀寫:參見

要求:對MYSQL數(shù)據(jù)庫的讀寫讀寫性能進行測試。支持多并發(fā)、支持調(diào)整事物提交記錄數(shù)。

注意事項:

要運行測試需要

1. 需要修改數(shù)據(jù)庫的配置信息DB_DRIVER、DB_URL、DB_USERNAME、DB_PASSWORD;

2.DB_URL中還要指定哪個數(shù)據(jù)庫。“dbc:mysql://localhost:3306/test”其中的test就是我鎖用的那個數(shù)據(jù)庫;

3. 修改TABLE_NAME指定數(shù)據(jù)庫測試的表名(此處是student表),測試程序會查詢這個表的定義來生成寫入SQL語句;

4.還有此語句 if (column.equalsIgnoreCase("name")) 中的那么為你創(chuàng)建的表的key,這個也要對用調(diào)整過來;

5. 修改concurrentList指定需要測試并發(fā)數(shù)列表,默認(rèn)測試1,5,10,20四種并發(fā)數(shù);

6. 修改batchSizeList指定每次測試的事務(wù)提交記錄數(shù)據(jù),默認(rèn)是100,200,500,1000

最后運行測試,會生成類似下面的結(jié)果:

測試完成后檢查該student表,輸入select * from student; 可以看到源源不斷的數(shù)據(jù)的輸出,插入的表項太多了。

具體查了多少數(shù)據(jù)呢?使用select count(*) from student;查看。

可能遇到的問題:

(1)UUID.randomUUID().toString()生成的主鍵會很長,因此主鍵name的長度應(yīng)設(shè)的長一些否則會出現(xiàn)如下報錯:

由上上截圖可以看到生成的主鍵還是蠻長的。

(2)每次測試的時候最好將上一次測試的table刪除重新建一個。否則測試的數(shù)據(jù)之間相差很大。

建立student表的SQL語句如下:

--刪除student表的SQL語句
drop table student;
--查詢表格項數(shù)大小的語句
select count(*) from student;
 
 
--建立student表,注意key的預(yù)留空間較大
create table student
(name varchar(120) not null, 
goal varchar(20) not null,
primary key(name));

程序代碼如下:

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Timestamp;
import java.sql.Types;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Formatter;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.UUID;
import java.util.concurrent.CountDownLatch;
import java.util.logging.Level;
import java.util.logging.Logger;
 
public class InsertTest {
 
    private static Logger logger = Logger.getLogger(InsertTest.class.getName());
 
    //驅(qū)動程序名  
    private static final String DB_DRIVER = "com.mysql.cj.jdbc.Driver";
    //URL指向要訪問的數(shù)據(jù)庫名mysql
	private static final String DB_URL = "jdbc:mysql://localhost:3306/test?rewriteBatchedStatements=true&useSSL=false&serverTimezone=UTC";
	//MySQL配置時的用戶名
	private static final String DB_USERNAME = "root";
    //MySQL配置時的密碼
	private static final String DB_PASSWORD = "…………";
 
    private static Random random = new Random(10000);
    //我們要測試的表的名稱
    private static final String TABLE_NAME = "student";
    private int batchSize;//一批提交的事務(wù)數(shù)
    private int concurrent;//
    private int sampling;//
 
    public static void main(String[] args) throws Exception {
        printHeader();
 
        int[] concurrentList = new int[]{1, 5, 10, 20};//默認(rèn)測試1,5,10,20個并發(fā)
        int[] batchSizeList = new int[] {100, 200, 500, 1000};//一批提交的事務(wù)數(shù)
        for (int concurrent : concurrentList) {
            for (int batchSize : batchSizeList) {
            	//對以上每種組合都run一次
                new InsertTest(batchSize, concurrent).run(true);
            }
            Thread.sleep(10000);
        }
    }
   /*-----------InsertTest類的構(gòu)造函數(shù)一-------------*/
    public InsertTest(final int batchSize, final int concurrent) throws Exception {
        this.batchSize = batchSize;
        this.concurrent = concurrent;
        this.sampling = 100;
    }
    /*-----------InsertTest類的構(gòu)造函數(shù)二-------------*/
    public InsertTest(final int batchSize, final int concurrent, final int sampling) throws Exception {
        this.batchSize = batchSize;
        this.concurrent = concurrent;
        this.sampling = sampling;
    }
    
    /*-----------開始運行run方法-------------*/
    public void run(boolean printResult) throws Exception {
        final List<Long> results = Collections.synchronizedList(new ArrayList<Long>());
        final CountDownLatch startGate = new CountDownLatch(concurrent);
        final CountDownLatch endGate = new CountDownLatch(concurrent);
 
        for (int idxConcurrent = 0; idxConcurrent < concurrent; idxConcurrent++) {
            new Thread(new Runnable() {
                public void run() {
                    startGate.countDown();
                    try {
                        long time = execute();
                        long avg = batchSize * sampling * 1000 / time;;
                        results.add(Long.valueOf(avg));
                    } catch(Exception ex) {
                        ex.printStackTrace();
                    } finally {
                        endGate.countDown();
                    }
                }
            }).start();
        }
        endGate.await();
 
        Collections.sort(results);
        //每種組合跑完之后都打印出一行數(shù)據(jù)
        if (printResult) {
            printResult(batchSize, concurrent, results);
        }
    }
 
    public long execute() throws Exception {
        Connection conn = getConnection();
        Map<String, Integer> columns = queryTableColumns(conn);
        String insertSQL = generateInsertSQL(columns);
        PreparedStatement ps = conn.prepareStatement(insertSQL);
        try {
            long start = System.currentTimeMillis();
            for (int i = 0; i < sampling; i++) {
                execute(conn, ps, columns);
            }
            long stop = System.currentTimeMillis();
            return stop - start;
        } catch(Exception ex) {
            logger.log(Level.SEVERE, null, ex);
            conn.rollback();
            conn.close();
            throw ex;
        } finally {
            conn.close();
        }
    }
    //執(zhí)行插入語句出錯。  ps:INSERT INTO student1(name,goal)VALUES(** NOT SPECIFIED **,** NOT SPECIFIED **)
    public void execute(Connection conn, PreparedStatement ps, Map<String, Integer> columns) throws Exception {
        try {
            for (int idx = 0; idx < batchSize; idx++) {
                int idxColumn = 1;
                //這個地方實際上是對每一列進行循環(huán)。(1)如果該列是key對應(yīng)的列………… (2)該列為普通列
                for (String column : columns.keySet()) {
                	//如果該列為name列即key對應(yīng)的列,就單獨為他生成一個主鍵。
                	//為了執(zhí)行忽略大小寫的比較,使用equalsIgnoreCase
                    if (column.equalsIgnoreCase("name")) {
                    	//給JDBC的SQL語句的占位符賦值的,即是下面的“?   connection.prepareStatement("insert into t_user values (?,?)");
                        //UUID.randomUUID().toString()是java JDK提供的一個自動生成主鍵的方法。
                        ps.setObject(idxColumn, UUID.randomUUID().toString());
                    } 
                    //否則就是普通列,隨便填充點東西進去就好了。
                    else {
                        ps.setObject(idxColumn, generateColumnValue(columns.get(column)));
                    }
                    idxColumn ++;
                }
                ps.addBatch();
            }
            //批量執(zhí)行SQL語句
            ps.executeBatch();
            conn.commit();
 
            ps.clearBatch();
        } 
        //如果上面出錯了就捕獲其異常
        catch (SQLException ex) {
            logger.log(Level.SEVERE, null, ex);
            if (null != ex.getNextException()) {
                logger.log(Level.SEVERE, null, ex.getNextException());
            }
            conn.rollback();
            throw ex;
        }
    }
    //根據(jù)獲取的列信息,生成插入的sql語句。
    private String generateInsertSQL(Map<String, Integer> columns) throws SQLException {
        StringBuilder sb = new StringBuilder();
        StringBuffer sbColumns = new StringBuffer();
        StringBuffer sbValues = new StringBuffer();
 
        sb.append("INSERT INTO ").append(TABLE_NAME);
 
        for (String column : columns.keySet()) {
            if (sbColumns.length() > 0) {
                sbColumns.append(",");
                sbValues.append(",");
            }
            sbColumns.append(column);
            sbValues.append("?");
        }
        sb.append("(").append(sbColumns).append(")");
        sb.append("VALUES");
        sb.append("(").append(sbValues).append(")");
        return sb.toString();
    }
 
    private Map<String, Integer> queryTableColumns(Connection conn) throws Exception {
        Map<String, Integer> columns = new LinkedHashMap<String, Integer>();
        String sql = "SELECT * FROM " + TABLE_NAME + " WHERE 1=0";
        Statement stmt = conn.createStatement();
        ResultSet rs = stmt.executeQuery(sql);
        ResultSetMetaData rsmd = rs.getMetaData();
        for (int i = 1; i <= rsmd.getColumnCount(); i++) {
            columns.put(rsmd.getColumnName(i), rsmd.getColumnType(i));
        }
        return columns;
    }
    
    //生成列值
    private Object generateColumnValue(int type) {
        Object obj = null;
        switch (type) {
            case Types.DECIMAL:
            case Types.NUMERIC:
            case Types.DOUBLE:
            case Types.FLOAT:
            case Types.REAL:
            case Types.BIGINT:
            case Types.TINYINT:
            case Types.SMALLINT:
            case Types.INTEGER:
                obj = random.nextInt(10000);
                break;
            case Types.DATE:
                obj = Calendar.getInstance().getTime();
                break;
            case Types.TIMESTAMP:
                obj = new Timestamp(System.currentTimeMillis());
                break;
            default:
                obj = String.valueOf(random.nextInt(10000));
                break;
        }
        return obj;
    }
    //連接MYSQL數(shù)據(jù)庫。
    private Connection getConnection() throws Exception {
        Class.forName(DB_DRIVER);
        Connection conn = DriverManager.getConnection(DB_URL, DB_USERNAME, DB_PASSWORD);
        conn.setAutoCommit(false);
        return conn;
    }
    //打印出表頭(即列的信息)
    private static void printHeader() {
        StringBuilder sb = new StringBuilder();
        sb.append("\n");
        sb.append(new Formatter().format("%15s|%15s|%15s|%15s|%15s", "BATCH_SIZE", "CONCURRENT", "AVG (r/s)", "MIN (r/s)", "MAX (r/s)"));
        System.out.println(sb.toString());
    }
    //打印每次跑完后的統(tǒng)計信息
    private static void printResult(int batch, int concurrent, List<Long> results) {
        Long total = Long.valueOf(0);
        for (Long result : results) {
            total += result;
        }
        StringBuilder sb = new StringBuilder();
        sb.append(new Formatter().format("%15s|%15s|%15s|%15s|%15s", batch, concurrent, (total/results.size()), results.get(0), results.get(results.size() - 1)));
        System.out.println(sb.toString());
    }
}

到此這篇關(guān)于MYSQL讀寫性能測試的簡單記錄的文章就介紹到這了,更多相關(guān)MYSQL讀寫性能測試內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 解決mysql與navicat建立連接出現(xiàn)1251錯誤

    解決mysql與navicat建立連接出現(xiàn)1251錯誤

    在本篇文章里小編給大家整理了一篇關(guān)于mysql與navicat建立連接出現(xiàn)1251錯誤怎么解決的技術(shù)文章,需要的朋友們參考下。
    2019-08-08
  • MySQL使用MyFlash快速恢復(fù)誤刪除和修改的數(shù)據(jù)

    MySQL使用MyFlash快速恢復(fù)誤刪除和修改的數(shù)據(jù)

    MyFlash 是由美團點評公司技術(shù)工程部開發(fā)并維護的一個開源工具,主要用于MySQL數(shù)據(jù)庫的DML操作的回滾,MyFlash的優(yōu)勢在于它提供了更多的過濾選項,使得回滾操作變得更加容易,本文將實驗通過 MyFlash 工具快速恢復(fù)誤刪除 或 誤修改的數(shù)據(jù),需要的朋友可以參考下
    2024-06-06
  • MySQL 8.0 驅(qū)動與阿里druid版本兼容問題解決

    MySQL 8.0 驅(qū)動與阿里druid版本兼容問題解決

    MySQL 8.0 驅(qū)動與阿里druid版本不兼容會導(dǎo)致有報錯問題,本文就詳細(xì)的介紹一下解決方法,具有一定的參考價值,感興趣的可以了解一下
    2021-07-07
  • Mysql復(fù)制表結(jié)構(gòu)、表數(shù)據(jù)的方法

    Mysql復(fù)制表結(jié)構(gòu)、表數(shù)據(jù)的方法

    這篇文章主要介紹了Mysql復(fù)制表結(jié)構(gòu)、表數(shù)據(jù)的方法,需要的朋友可以參考下
    2015-10-10
  • MySQL多表查詢與7種JOINS的實現(xiàn)舉例

    MySQL多表查詢與7種JOINS的實現(xiàn)舉例

    最近學(xué)習(xí)了多表查詢,對此做一些筆記的整理,下面這篇文章主要給大家介紹了關(guān)于MySQL多表查詢與7種JOINS實現(xiàn)的相關(guān)資料,文中通過實例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-02-02
  • MySQL中NOT IN填坑之列為null的問題解決

    MySQL中NOT IN填坑之列為null的問題解決

    這篇文章主要給大家介紹了關(guān)于MySQL中NOT IN填坑之列為null的問題解決的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用MySQL具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-11-11
  • MySQL數(shù)據(jù)庫索引的弊端及合理使用

    MySQL數(shù)據(jù)庫索引的弊端及合理使用

    索引可以說是數(shù)據(jù)庫中的一個大心臟了,如果說一個數(shù)據(jù)庫少了索引,那么數(shù)據(jù)庫本身存在的意義就不大了,和普通的文件沒什么兩樣,本文從細(xì)節(jié)和實際業(yè)務(wù)的角度看看在MySQL中B+樹索引好處
    2021-11-11
  • mysql忘記密碼怎么辦

    mysql忘記密碼怎么辦

    mysql忘記密碼怎么辦?這篇文章主要為大家詳細(xì)介紹了MySQL忘記密碼的解決辦法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-06-06
  • mysql int(3)與int(11)的區(qū)別詳解

    mysql int(3)與int(11)的區(qū)別詳解

    這篇文章主要介紹了mysql int(3)與int(11)的區(qū)別詳解的相關(guān)資料,需要的朋友可以參考下
    2016-09-09
  • 關(guān)于mysql基礎(chǔ)知識的介紹

    關(guān)于mysql基礎(chǔ)知識的介紹

    本篇文章是對mysql的基礎(chǔ)知識進行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-06-06

最新評論

大同县| 三门县| 乌兰察布市| 安乡县| 哈巴河县| 永安市| 新龙县| 沂源县| 历史| 苗栗县| 个旧市| 富阳市| 柯坪县| 五指山市| 古田县| 望奎县| 文山县| 大渡口区| 晋江市| 台江县| 九寨沟县| 色达县| 碌曲县| 曲周县| 清苑县| 庄河市| 肥乡县| 抚宁县| 青河县| 镶黄旗| 溧阳市| 温泉县| 湟源县| 武夷山市| 三河市| 定兴县| 汶川县| 肥城市| 盐池县| 名山县| 安平县|