MySQL性能压力测试

针对数据库的测试,市面上已经有很多工具了,Google 上搜一下 sql testing tool , 他为你选出的工具,琳琅满目,看花双眼。

比如:40+ Best Database Testing Tools - Popular Data Testing Solutions 这篇文章列举了总共 43 个测试工具,可以用来完成 SQL 的测试,包括生成测试数据,功能性测试,逻辑性测试,当然还有压力测试。

在这里罗列几个工具,以便有应用场景的时候,可以拿起来直接用。

现在的应用系统,一般都会有好几层,比如 UI, Access Layer, Business Layer, 数据库。每一层都有自己独立的测试工具,下面的工具可能会同时支持其中1,2层对应的测试。

Test Data Generator:

1 data factory

商业用数据库数据生成工厂。主要特点有:

    1.生成数据

    2.压力测试



2  MockupData

3 DTM Data Generator
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

SQL-Based Tools:

1. SQL Server Database tools

2. SQL Test: uses tSQLt framework to make test on views, stored procedures and functions。 使用的是 tSQLt 测试框架,用来测试试图,存储过程以及函数

3. tSQLt:dedicated to sql server

4. oracle sql developer:

5. NoSQLUnit:

6. NoSQLMap:

7. SeLite:combination of selenium and SQLite, known as Selenium extension

8. SQLMap: open source tool for SQLite, MySQL, SQL Server, DB2, PostgreSQL
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

DB based Level Testing tools:

  1. HammerDB: open source tool for database load testing, used as benchmarking tool for sql server, mysql, db2, oracle。 这款工具的优点在于,他是 
    open 
    source即开源的工具,意味着你可以完全看到他的测试方案。看不到测试方案的工具,其实对自己理解测试报告,是有障碍的,比如并发是怎么协调的,测试用的逻辑脚本是不是能体现出测试要求。

UI Enhanced Tools: 自带绚丽UI的一体化工具

1. Toad。 这款工具就不用多说了,和 Oracle 打交道并且是大厂项目的话,Toad 基本是必用工具。

2. DBVisualizer: toad 旗下的可视化开发工具, 最有用的一点是可以快速建立ER图

3. Database benchmark: open source tool for performing stress testing on a database that contains a large volume of data. Graphic visualization and reporting options are advanced features of this tool. 开源工具,可视化配置测试用例,性能测试报告。
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

针对 MySQL, Oracle, MariaDB :

  1. Navicat: for mySQL, also manage data in sql server , oracle, mysql, SQLite

  2. LoadRunner for Oracle:

    扫描二维码关注公众号,回复: 1169770 查看本文章

在 Brent Ozar 的博客上找到一个非常棒的工具: SQLQueryStress, 并且是open source 开源的。可以从github 上下载并使用。

https://www.brentozar.com/archive/2015/05/how-to-fake-load-tests-with-sqlquerystress

说了那么多,这才是本文的主角。

如果你是手机的 Geek, 我想你一定会喜欢 Andriod.

iPhone 当然也有玩头,只不过 App Store 上线一应用,审批实在麻烦。

这款 SQLQueryStress 就像是 Andriod 上的应用一样,随你拆开来玩,一睹内部玄妙的机关。Github 是个重武器库,当今的软件替代品差不多都能找到。大家看到的题图,都是用了 GitHub 上的小爬虫,从 Instagram 上扣下来的。

首先交代测试环境:

1 测试工具: SQLQueryStress

下载路径:https://github.com/ErikEJ/SqlQueryStress
  • 1
  • 2

2 测试用 SQL Server 服务器:

个人的vmware 虚拟机,配置较低

Windows Server 2012

2GB RAM

Intel Core i3CPU @3.07 GHZ

20GB SSD
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

3 测试方案:

3.1 用户响应时间:读

3.2 服务器 CPU 利用率
  • 1
  • 2
  • 3
  • 4

今天暂时针对 CPU 做测试。

  1. 10 个并发的情况下, 平均响应时间在 0.4973 秒。可以说妥妥的。但细心的朋友肯定注意到,其实这里只是单纯的运行同一个 SQL, 想想是不是哪里不够严谨,哪里可以提高,哪里是瓶颈?

这里写图片描述

2 200个并发下,平均响应时间已经超过 1s, 接近 2s 了

这里写图片描述

当这 200个并发,一直在运行着查询的时候,即使是同一个查询,响应时间也已经不可接受了。

这里写图片描述

我们在本次实验中,应用的是同一段脚本,同一段脚本运行完了之后,执行计划会被缓存起来,相应的数据,也会在数据库的缓存中保留下来,这样的环境下,连续的发出查询请求,其实对服务器的CPU考核已经不是很严格了,不需要硬解析,不需要从数据库磁盘拿出数据,但并发的响应时间依然不合格。

假如我们用一个总调度,根据线程ID来随机抽取一个只读存储过程进行查询,这样的查询对CPU的考验才叫严格与真实。

刚才我们用10个并发的时候,系统没有明显的压力,响应时间够快。

这次我们就做10个存储过程,当10个并发同时调用这10个存储过程的时候,检查响应时间,是不是依然合格!

1 利用 AdventureWorks 数据库,编写10个简单的存储过程

2 编写一个总调度存储过程,根据各自的线程ID,即 session_id, 来随机调取其中一个存储过程

10 个简单的存储过程可以这么快速生成:

DECLARE @sql_body NVARCHAR(max);



DECLARE my_cur CURSOR

FOR

SELECT TOP 10 'create procedure ' + schema_name(schema_id) + '.get' + NAME + ' as begin ' + 'select count(*) as cnt from ' + schema_name(schema_id) + '.' + NAME + ' end  ' + CHAR(10) + 'go'

FROM sys.objects

WHERE type_desc = 'user_table'



OPEN my_cur



FETCH NEXT

FROM my_cur

INTO @sql_body



PRINT @sql_body



WHILE @@fetch_status = 0

BEGIN

    FETCH NEXT

    FROM my_cur

    INTO @sql_body



    PRINT @sql_body;

END



CLOSE my_cur



DEALLOCATE my_cur

GO
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57

总调度存储过程:

CREATE PROCEDURE dbo.usp_randRunQuery @threads INT = 10

AS

BEGIN

DECLARE @sql_body NVARCHAR(max);



CREATE TABLE #temp_procs (

procedurename NVARCHAR(max)

,id INT identity(1, 1)

)



INSERT INTO #temp_procs

SELECT TOP 10 'exec ' + schema_name(schema_id) + '.' + NAME

FROM sys.objects

WHERE type_desc = 'SQL_STORED_PROCEDURE'

ORDER BY create_date DESC



SELECT @sql_body = procedurename

FROM #temp_procs

WHERE id = @@spid % @threads



EXEC sp_executesql @stmt = @sql_body;



DROP TABLE #temp_procs

END
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47

当 10 个线程,调用不同的存储过程时,响应速度依旧可以。有峰值,但不过百

这里写图片描述

这里写图片描述

在执行过程中,我发现并不是每一次的 iteration 都是固定的线程,有可能每一次执行,分配的处理线程会改变,因此需要多循环几次,来保证每一个存储过程都被调用,并且一段时间内有足够多的并发在运行

我的猜想是,到了一定的时间之后,相应时间会趋稳。

所以做了一个记录每一个查询的执行时间的功能,如下:

1 加一张Log表:

create table execution_log(execid bigint identity(1,1), spid int, 
procname nvarchar(2000),start_dt datetime, end_dt datetime)

2 修改我们的调度过程

CREATE PROCEDURE dbo.usp_randRunQuery @threads INT = 10

AS

BEGIN

    BEGIN

        DECLARE @execid BIGINT

        DECLARE @sql_body NVARCHAR(2000);



        CREATE TABLE #temp_procs (

            procedurename NVARCHAR(2000)

            ,id INT identity(1, 1)

            )



        INSERT INTO #temp_procs

        SELECT TOP 10 'exec ' + schema_name(schema_id) + '.' + NAME

        FROM sys.objects

        WHERE type_desc = 'SQL_STORED_PROCEDURE'

        ORDER BY create_date DESC



        SET IDENTITY_INSERT #temp_procs OFF



        INSERT INTO #temp_procs (

            id

            ,procedurename

            )

        SELECT 0

            ,procedurename

        FROM #temp_procs

        WHERE id = 6



        SET IDENTITY_INSERT #temp_procs ON



        SELECT @sql_body = procedurename

        FROM #temp_procs

        WHERE id = @@spid % @threads % 10



        INSERT INTO execution_log (

            spid

            ,procname

            ,start_dt

            )

        VALUES (

            @@spid

            ,@sql_body

            ,getutcdate()

            )



        SELECT @execid = SCOPE_IDENTITY()



        EXEC sp_executesql @stmt = @sql_body;



        UPDATE execution_log

        SET end_dt = getutcdate()

        WHERE execid = @execid;



        DROP TABLE #temp_procs

    END

END
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113

这里写图片描述

果不出所料,再多的请求,相应时间也稳定下来了

猜你喜欢

转载自blog.csdn.net/weixin_38399962/article/details/80306714
今日推荐