16.3. Speeding Up Read-Only Data Access

Problem

You want to speed up read-only data access to a database in your application.

Solution

Use a DataReader instead of a DataAdapter to access the data.

Example 16-7 through Example 16-9 show the .aspx file and VB and C# code-behind files for our application that demonstrates the performance difference between a DataReader and a DataAdapter using the OleDB managed provider. Figure 16-2 shows the output of the application. Refer to Recipe 16.4 for an equivalent example using the SQL Server managed provider.

Measuring data reader and data adapter performance output

Figure 16-2. Measuring data reader and data adapter performance output

Discussion

The common language runtime (CLR) provides two primary methods for reading data from a database. The first is to use a DataReader, and the second is to use a DataAdapter in conjunction with a DataTable or DataSet.

The DataReader provides forward, read-only access to the data read from the database. It provides no mechanisms for randomly accessing the data.

A DataAdapter, along with a DataTable or DataSet, provides random access to data. In addition, the data can be changed in the DataTable or DataSet and the DataAdapter can be used to update the data in the database.

Of the two access methods, the DataReader is the lightest and fastest and is preferable when you only need to read the data, as reflected in the results we show for our sample application in Figure 16-2. Our example reads 10K and 100K records from a SQL Server database table containing 500K rows. The table contains five columns, of which three are retrieved in the query. The data indicates that using a DataAdapter is anywhere from 12% to 21% slower than using a DataReader.

See Also

Recipe 16.4

Example 16-7. Measuring data reader and data adapter performance (.aspx)

<%@ Page Language="vb" AutoEventWireup="false" 
         Codebehind="CH16DataAccessPerformanceVB.aspx.vb" 
         Inherits="ASPNetCookbook.VBExamples.CH16DataAccessPerformanceVB" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
  <head>
    <title>Data Access Performance</title>
    <link rel="stylesheet" href="css/ASPNetCookbook.css">
  </head>
  <body leftmargin="0" marginheight="0" marginwidth="0" topmargin="0">
    <form id="frmDataAccessPerformance" method="post" runat="server">
      <table width="100%" cellpadding="0" cellspacing="0" border="0">
        <tr>
          <td align="center">
            <img src="images/ASPNETCookbookHeading_blue.gif">
          </td>
        </tr>
        <tr>
          <td class="dividerLine">
            <img src="images/spacer.gif" height="6" border="0"></td>
        </tr>
      </table>
      <table width="90%" align="center" border="0">
        <tr>
          <td align="center">&nbsp;</td>
        </tr>
        <tr>
          <td align="center" class="PageHeading">
            Data Access Performance Using OleDB Provider (VB)
          </td>
        </tr>
        <tr>
          <td><img src="images/spacer.gif" height="10" border="0"></td>
        </tr>
        <tr>
          <td align="center">
            <table width="100%" align="center" border="0">
              <tr>
                <td align="center">Rows Read</td>
                <td align="center">OleDBDataReader Time (mSec)</td>
                <td align="center">OleDBDataAdaptor Time (mSec)</td>
              </tr>
              <tr>
                <td align="center">10,000</td>
                <td id="cellDR10K" runat="server" align="center"></td>
                                  <td id="cellDA10K" runat="server" align="center"></td>
              </tr>
              <tr>
                <td align="center">100,000</td>
                <td id="cellDR100K" runat="server" align="center"></td>
                                  <td id="cellDA100K" runat="server" align="center"></td>
              </tr>
            </table>
          </td>
        </tr>
      </table>
    </form>
  </body>
</html>

Example 16-8. Measuring data reader and data adapter performance code-behind (.vb)

Option Explicit On 
Option Strict On
'-----------------------------------------------------------------------------
'
'   Module Name: CH16DataAccessPerformanceVB.aspx.vb
'
'   Description: This module provides the code behind for the 
'                CH16DataAccessPerformanceVB.aspx page
'
'*****************************************************************************
Imports Microsoft.VisualBasic
Imports System
Imports System.Configuration
Imports System.Data
Imports System.Data.OleDb

Namespace ASPNetCookbook.VBExamples
  Public Class CH16DataAccessPerformanceVB
    Inherits System.Web.UI.Page

    'controls on the form
    Protected cellDR10K As System.Web.UI.HtmlControls.HtmlTableCell
    Protected cellDR100K As System.Web.UI.HtmlControls.HtmlTableCell
    Protected cellDA10K As System.Web.UI.HtmlControls.HtmlTableCell
    Protected cellDA100K As System.Web.UI.HtmlControls.HtmlTableCell

    '*************************************************************************
    '
    '   ROUTINE: Page_Load
    '
    '   DESCRIPTION: This routine provides the event handler for the page load
    '                event.  It is responsible for initializing the controls 
    '                on the page.
    '-------------------------------------------------------------------------
    Private Sub Page_Load(ByVal sender As System.Object, _
                          ByVal e As System.EventArgs) Handles MyBase.Load
      Dim strConnection As String
      Dim elapsedTime As TimeSpan

      'get the connection string from web.config
      strConnection = _
          ConfigurationSettings.AppSettings("dbConnectionString")

      'get times for 10,000 records
                        elapsedTime = getDataAdapterTime(strConnection, 10000)
                        cellDA10K.InnerText = elapsedTime.TotalMilliseconds.ToString("0.0000")

                        elapsedTime = getDataReaderTime(strConnection, 10000)
                        cellDR10K.InnerText = elapsedTime.TotalMilliseconds.ToString("0.0000")

                        'get times for 100,000 records
                        elapsedTime = getDataAdapterTime(strConnection, 100000)
                        cellDA100K.InnerText = elapsedTime.TotalMilliseconds.ToString("0.0000")
                        elapsedTime = getDataReaderTime(strConnection, 100000)
                        cellDR100K.InnerText = elapsedTime.TotalMilliseconds.ToString("0.0000")
    End Sub  'Page_Load

    '*************************************************************************
    '
    '   ROUTINE: getDataReaderTime
    '
    '   DESCRIPTION: This routine retrieves the passed number of records from
    '                the database using an OleDBDataReader and returns the
    '                elapsed time
    '-------------------------------------------------------------------------
    Private Function getDataReaderTime(ByVal strConnection As String, _
                                                         ByVal numberOfRecords As Integer) _
                                       As TimeSpan

                        Dim dbConn As OleDbConnection
                        Dim dCmd As OleDbCommand
                        Dim dr As OleDbDataReader
                        Dim strSQL As String
                        Dim startTime As DateTime
                        Dim elapsedTime As TimeSpan
                        Dim bookTitle As String
                        Dim isbn As String
                        Dim price As Decimal

                        Try
                          'open connection to database
                          dbConn = New OleDbConnection(strConnection)
                          dbConn.Open( )

                          startTime = DateTime.Now( )

                          'build the query string and get the data from the database
                          strSQL = "SELECT Top " & numberOfRecords.ToString( ) & " " & _
                                   "BookTitle, ISBN, Price " & _
                                   "FROM PerformanceTesting " & _
                                   "ORDER BY PerformanceTestingID"

                          'read the data from the database
                          dCmd = New OleDbCommand(strSQL, dbConn)
                          dr = dCmd.ExecuteReader( )
                          Do While (dr.Read( ))
                            bookTitle = CStr(dr.Item("BookTitle"))
                            isbn = CStr(dr.Item("ISBN"))
                            price = CDec(dr.Item("Price"))
                          Loop

                          'return the elapsed time
                          elapsedTime = DateTime.Now.Subtract(startTime)
                          getDataReaderTime = elapsedTime

                        Finally
                          'clean up
                          If (Not IsNothing(dbConn)) Then
                            dbConn.Close( )
                          End If
                        End Try
                      End Function  'getDataReaderTime

    '*************************************************************************
    '
    '   ROUTINE: getDataAdapterTime
    '
    '   DESCRIPTION: This routine retrieves the passed number of records from
    '                the database using an OleDbDataAdapter and returns the
    '                elapsed time
    '-------------------------------------------------------------------------
    Private Function getDataAdapterTime(ByVal strConnection As String, _
                                                          ByVal numberOfRecords As Integer) _
                                       As TimeSpan
                        Dim dbConn As OleDbConnection
                        Dim da As OleDbDataAdapter
                        Dim dTable As DataTable
                        Dim strSQL As String
                        Dim startTime As DateTime
                        Dim elapsedTime As TimeSpan

                        Try
                          'open connection to database
                          dbConn = New OleDbConnection(strConnection)
                          dbConn.Open( )

                          startTime = DateTime.Now( )

                          'build the query string and get the data from the database
                          strSQL = "SELECT Top " & numberOfRecords.ToString( ) & " " & _
                                   "BookTitle, ISBN, Price " & _
                                   "FROM PerformanceTesting " & _
                                   "ORDER BY PerformanceTestingID"

                          'read the data from the database
                          da = New OleDbDataAdapter(strSQL, dbConn)
                          dTable = New DataTable
                          da.Fill(dTable)

                          'return the elapsed time
                          elapsedTime = DateTime.Now.Subtract(startTime)
                          getDataAdapterTime = elapsedTime

                        Finally
                          'clean up
                          If (Not IsNothing(dbConn)) Then
                            dbConn.Close( )
                          End If
                        End Try
                      End Function  'getDataAdapterTime
                    End Class  'CH16DataAccessPerformanceVB
End Namespace

Example 16-9. Measuring data reader and data adapter performance code-behind (.cs)

//----------------------------------------------------------------------------
//
//   Module Name: CH16DataAccessPerformanceCS.aspx.cs
//
//   Description: This module provides the code behind for the 
//                CH16DataAccessPerformanceCS.aspx page
//
//****************************************************************************
using System;
using System.Configuration;
using System.Data;
using System.Data.OleDb;

namespace ASPNetCookbook.CSExamples
{
  public class CH16DataAccessPerformanceCS : System.Web.UI.Page
  {
    // controls on the form
    protected System.Web.UI.HtmlControls.HtmlTableCell cellDR10K;
    protected System.Web.UI.HtmlControls.HtmlTableCell cellDR100K;
    protected System.Web.UI.HtmlControls.HtmlTableCell cellDA10K;
    protected System.Web.UI.HtmlControls.HtmlTableCell cellDA100K;
    
    //************************************************************************
    //
    //   ROUTINE: Page_Load
    //
    //   DESCRIPTION: This routine provides the event handler for the page 
    //                load event.  It is responsible for initializing the 
    //                controls on the page.
    //------------------------------------------------------------------------
    private void Page_Load(object sender, System.EventArgs e)
    {
      String strConnection;
      TimeSpan elapsedTime;

      // get the connection string from web.config
      strConnection =
          ConfigurationSettings.AppSettings["dbConnectionString"];

      // get times for 10,000 records
                        elapsedTime = getDataAdapterTime(strConnection, 10000);
                        cellDA10K.InnerText = elapsedTime.TotalMilliseconds.ToString("0.0000");

                        elapsedTime = getDataReaderTime(strConnection, 10000);
                        cellDR10K.InnerText = elapsedTime.TotalMilliseconds.ToString("0.0000");

                        // get times for 100,000 records
                        elapsedTime = getDataAdapterTime(strConnection, 100000);
                        cellDA100K.InnerText = elapsedTime.TotalMilliseconds.ToString("0.0000");

                        elapsedTime = getDataReaderTime(strConnection, 100000);
                        cellDR100K.InnerText = elapsedTime.TotalMilliseconds.ToString("0.0000");
    }  // Page_Load

    //************************************************************************
    //
    //   ROUTINE: getDataReaderTime
    //
    //   DESCRIPTION: This routine retrieves the passed number of records from
    //                the database using an OleDBDataReader and returns the
    //                elapsed time.
    //------------------------------------------------------------------------
    private TimeSpan getDataReaderTime(String strConnection,
                                                         int numberOfRecords)
                      {
                        OleDbConnection dbConn = null;
                        OleDbCommand dCmd = null;
                        OleDbDataReader dr = null;
                        string strSQL = null;
                        DateTime startTime;
                        TimeSpan elapsedTime;
                        String bookTitle;
                        String isbn;
                        Decimal price;

                        try
                        {
                          // open connection to database
                          dbConn = new OleDbConnection(strConnection);
                          dbConn.Open( );

                          startTime = DateTime.Now;

                          // build the query string used to get the data from the database
                          strSQL = "SELECT Top " + numberOfRecords.ToString( ) + " " +
                                   "BookTitle, ISBN, Price " +
                                   "FROM PerformanceTesting " +
                                   "ORDER BY PerformanceTestingID";

                          // read the data from the database
                          dCmd = new OleDbCommand(strSQL, dbConn);
                          dr = dCmd.ExecuteReader( );
                          while (dr.Read( ))
                          {
                            bookTitle = (String)(dr["BookTitle"]);
                            isbn = (String)(dr["ISBN"]);
                            price = Convert.ToDecimal(dr["Price"]);
                          }

                          //return the elapsed time
                          elapsedTime = DateTime.Now.Subtract(startTime);
                          return(elapsedTime);
                        }

                        finally
                        {
                          // clean up
                          if (dbConn != null)
                          {
                            dbConn.Close( );
                          }
                        }
                      }  // getDataReaderTime

    //************************************************************************
    //
    //   ROUTINE: getDataAdapterTime
    //
    //   DESCRIPTION: This routine retrieves the passed number of records from
    //                the database using an OleDbDataAdapter and returns the
    //                elapsed time.
    //------------------------------------------------------------------------
    private TimeSpan getDataAdapterTime(String strConnection,
                                                          int numberOfRecords)
                      {
                        OleDbConnection dbConn = null;
                        OleDbDataAdapter da = null;
                        DataTable dTable = null;
                        string strSQL = null;
                        DateTime startTime;
                        TimeSpan elapsedTime;

                        try
                        {
                          // open connection to database
                          dbConn = new OleDbConnection(strConnection);
                          dbConn.Open( );
                          startTime = DateTime.Now;

                          // build the query string used to get the data from the database
                          strSQL = "SELECT Top " + numberOfRecords.ToString( ) + " " +
                                   "BookTitle, ISBN, Price " +
                                   "FROM PerformanceTesting " +
                                   "ORDER BY PerformanceTestingID";

                          // read the data from the database
                          da = new OleDbDataAdapter(strSQL, dbConn);
                          dTable = new DataTable( );
                          da.Fill(dTable);

                          // return the elapsed time
                          elapsedTime = DateTime.Now.Subtract(startTime);
                          return(elapsedTime);
                        }

                        finally
                        {
                          // clean up
                          if (dbConn != null)
                          {
                            dbConn.Close( );
                          }
                        }
                      }  // getDataAdapterTime
  }  // CH16DataAccessPerformanceCS
}
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset