Click here to Skip to main content
15,867,330 members
Articles / Web Development / ASP.NET
Article

A simple VB.NET stress utility for SQL Server 2000

Rate me:
Please Sign up or sign in to vote.
4.47/5 (21 votes)
14 Apr 20047 min read 229.2K   1.2K   84   19
This article describes a VB.NET tool to test the performances of a Microsoft SQL Server 2000 user database.

Sample Image - DBstressUtil.gif

Introduction

As any developer knows, the tuning phase of any data access application development implies the analysis of the database response time, possibly followed by a refinement of some database design aspects (i.e. reviewing some poorly coded stored procedures or the adopted indexing strategies).

This kind of optimization can't be unaware of high load scenarios, so it's a good habit to test the application under "stressed" conditions. For example, an ASP.NET Web Application will be typically tested with stress tools like Microsoft Application Center Test (a.k.a. ACT), that allow you to simulate multiple simultaneous users requesting the web site's ASPX pages.

Under some circumstances, however, these stress test environments are not suitable to point out performance bottlenecks on the database side. With ACT, for example, you can take some measurements about the web server response times, on a page by page basis; but what you are measuring is the web server's response time, that consists of the time spent to process/render the web page plus the time spent in accessing data from the database server. And sometimes it is not simple to understand if the poor performance cause resides in the ASPX page code or in the involved database activity.

So, a new need arises: the need to measure the pure database response time. This is true especially during the development and testing of Web Applications (where you want to measure the database response time, without the noise introduced by the web server processing), but also in many other multi-tier situations, where you want to evaluate the database performance excluding the influences of upper software layers.

Of course, this kind of measurements on the database side can be collected through tools like Microsoft SQL Server Profiler while the web application pages are being hit by the ACT-simulated workload. But, if you collect measures in this way, you need to keep in mind that the database workload comes always from the web server, and this can be sometimes not realistic in case of differences in the web infrastructure between the test environment and the real environment. To make an example: suppose that your production architecture includes a web server farm that you don't have in the test environment; after observing the test environment performance, you can perhaps imagine how your web application will scale on production by the ASP.NET point of view, but it's hard to tell how the database will behave in production, where it will be exposed to the workload generated by multiple web servers.

The tool presented in this article, named DBstressUtil, is a simple database stress utility that tries to address these problems, focusing on the database performance analysis and keeping away any other application layer (data access, business logic, user interface components) that might add noise to the database response time measurement.

Background

When I faced the problem of simulating a workload to stress a SQL Server database, someone suggested me to take a look of the Microsoft SQL Server 2000 Resource Kit. In fact, the Resource Kit contains a VB6 utility named Database Hammer, a tool to test the performance of a SQL Server 2000 instance: it creates its own work tables and then submits tons of INSERT/UPDATE statements on that tables, simulating concurrent users connected to the database. So you can observe if a particular installation of SQL Server performs well.

But my goal was different: I needed to test not a generic instance of SQL Server, but a specific database, with its indexes, stored procedures, triggers and so on. So, Database Hammer was not useful for me, but I liked the basic idea of simulating concurrent database users through a Windows Application. From there to conceive DBstressUtil, the step was short.

How the utility works

DBstressUtil is coded as a Windows Forms VB.NET application and it is designed to work on a SQL Server 2000 database (of course, using the SQL Server .NET Managed Provider classes of the System.Data.SqlClient namespace).

DBstressUtil simulates multiple database users submitting T-SQL scripts (executing stored procedures or simply sending DML commands). These scripts are taken from an input text file (that we'll call "test script" from now on), that has to be prepared in advance, with a simple text editor.

When you run DBstressUtil, on the main form, you can configure some execution options as:

  • the number of simultaneous users (a.k.a. "client instances") to be simulated (see txtInstances),
  • the time between the start of the activity of a user and of the subsequent user (see txtClientShift),
  • the interval between each command executed by each single simulated user (see txtInterval).

When you start the stress test, a number of concurrent threads are created and each of these begins the execution of the T-SQL commands taken from the "test script". Each command execution time (in milliseconds) is measured and recorded on a CSV output file, for an easy post-processing of collected data. During the test, you can monitor the number of currently running simulated client instances (see txtRunningInstances), and the number of the total executed commands (see txtDoneCommands).

A test run has to be considered over when the number of the total executed commands equals the number of client instances multiplied by the number of commands included in the "test script". At this time, you can inspect the CSV log file produced by DBstressUtil; this output file will contain records made up of these fields:

  • the starting date and time of the execution of a particular command by a particular client instance;
  • the ID (ranging from 1 to txtInstances value) of the simulated client instance that executed the command;
  • the ID (ranging from 1 to the total number of commands included in the "test script") of the executed command;
  • the execution time (in milliseconds) related to that particular command submitted by that particular client instance.

And now, something about the code...

Each simulated client instance is an instance of the ClientProc class. The StartClientProcess method of this class is responsible for all the simulation processes of a single client, and it is invoked for each instance of ClientProc on a new thread by the main program, as shown here:

VB
Dim i As Integer        ' Counter of Client process instances
Dim x() As ClientProc   ' Array of Client process instances
...
x(i) = New ClientProc
x(i).ConnectString = ...
x(i).WaitInterval = Convert.ToInt32(txtInterval.Text)
x(i).CommandFile = txtCommandFile.Text
x(i).LogFile = txtLogFile.Text
...
Dim t As New Thread(AddressOf x(i).StartClientProcess)
t.Start()

Steps of the StartClientProcess method are:

  • when starting, to increment the "currently running instances" counter;
  • to load the "test script" in a string array (see LoadCommandFile() private method);
  • to loop through the commands of the "test script", and, for each of them:
    • to execute it via a SqlCommand.ExecuteNonQuery() method;
    • to log its execution time on the CSV output file;
    • to increment the "total executed commands" counter;
    • to wait the specified pause interval before the next command execution;
  • when ending, to decrement the "currently running instances" counter.

All the code accessing resources that are shared among multiple client instances is protected by a Mutex (for example: the output file access, or the update of UI elements of the MainForm).

Finally, keep in mind...

  • that the "test script" must contain a valid T-SQL script on each line; so, a single line in the "test script" can be in the form of:
    • a single EXEC stored_procedure @param=value command;
    • a single SELECT / INSERT / UPDATE / DELETE command;
    • a more complicated T-SQL script, composed by multiple DML commands.
  • that in the "test script" you can include comment lines, that make more readable your scripts and are ignored by DBstressUtil (also in the implicit numbering of the submitted commands); a comment line is a line beginning with "--" (two hypens); all other lines are considered as valid commands (or complete T-SQL scripts) to be submitted towards the SQL Server database;
  • that DBstressUtil uses the same connection string for each simulated client instance: so, evaluating your measurements, you need to keep into account the effects of database connection pooling (if that feature is enabled);
  • that DBstressUtil currently doesn't manage database errors: so, evaluating your measurements, remember that an extremely fast command might be a command that actually produces a SQL error...
  • that DBstressUtil currently doesn't support the "smooth" interruption of a test run: so, be careful when you configure your "test scripts" and your execution parameters, to avoid the need to kill the application because of a too long running test.
  • that the commands.txt file included in the Zip archive contains very simple commands that operate on the sample Northwind database: of course, due to those trivial commands and the database size, using the commands.txt file on the Northwind database is NOT the circumstance where you will find DBstressUtil useful! Please, try DBstressUtil on bigger databases, especially if they are full of business logic coded in complex T-SQL code... and enjoy!

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Technical Lead
Italy Italy
I was born in 1970.

My first computer experience dates back to early 80s, with a Sinclair ZX81.
From that time on, as many "friends" say, my IT-illness has increased year by year.

I graduated in Electronic Engineering and earned the following Microsoft certifications:
MCP, MCT, MCDBA, MCSD, MCAD, MCSD for .NET (early achiever).

I worked in IT as a developer, a teacher, a consultant, a technical writer, a technical leader.
IT knowledge applied to real life is my primary interest and focus.

Comments and Discussions

 
QuestionDBStressUtil on SQL Server 2005? Pin
Michael Gjernes28-Feb-08 20:17
Michael Gjernes28-Feb-08 20:17 
GeneralRe: DBStressUtil on SQL Server 2005? Pin
Alberto Venditti2-Mar-08 11:08
Alberto Venditti2-Mar-08 11:08 
GeneralRe: DBStressUtil on SQL Server 2005? Pin
Alberto Venditti2-Mar-08 11:36
Alberto Venditti2-Mar-08 11:36 
GeneralDatabase comparison Pin
Lokanatha.Reddy19-Dec-06 21:44
Lokanatha.Reddy19-Dec-06 21:44 
GeneralRe: Database comparison Pin
Alberto Venditti20-Dec-06 2:50
Alberto Venditti20-Dec-06 2:50 
GeneralCan't find log file Pin
Philasdfvjav13-Jul-06 14:43
Philasdfvjav13-Jul-06 14:43 
I can't find the log file either. I put it in root of C: still can't find it. I'm also not sure if it's running as I see no instances.

Thanks for any help

PhilC
GeneralRe: Can't find log file Pin
Alberto Venditti13-Jul-06 23:27
Alberto Venditti13-Jul-06 23:27 
GeneralRe: Can't find log file Pin
Philasdfvjav14-Jul-06 6:43
Philasdfvjav14-Jul-06 6:43 
QuestionHow to feel if the server is good or bad Pin
InnerBit6-Jul-06 13:06
InnerBit6-Jul-06 13:06 
AnswerRe: How to feel if the server is good or bad Pin
Alberto Venditti6-Jul-06 22:20
Alberto Venditti6-Jul-06 22:20 
QuestionError when trying to run? Pin
zashah@gmail.com20-Jun-06 1:00
zashah@gmail.com20-Jun-06 1:00 
AnswerRe: Error when trying to run? Pin
Alberto Venditti22-Jun-06 22:28
Alberto Venditti22-Jun-06 22:28 
AnswerRe: Error when trying to run? Pin
Vasudevan Deepak Kumar1-Feb-07 21:01
Vasudevan Deepak Kumar1-Feb-07 21:01 
GeneralGreat tool Pin
ArnoDisser7-Apr-06 11:23
ArnoDisser7-Apr-06 11:23 
Generalwhere and how to find log.csv Pin
mzahmed12343-Mar-06 7:33
mzahmed12343-Mar-06 7:33 
GeneralRe: where and how to find log.csv Pin
Alberto Venditti5-Mar-06 5:23
Alberto Venditti5-Mar-06 5:23 
Generaldeadlock Pin
cberneburg19-Aug-04 6:07
cberneburg19-Aug-04 6:07 
General2 minor Improvements Pin
thomasswilliams20-Apr-04 15:21
thomasswilliams20-Apr-04 15:21 
GeneralRe: 2 minor Improvements Pin
Shah Z. S19-Jun-04 3:06
Shah Z. S19-Jun-04 3:06 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.