Getting the data out of the DataReader

2 minuut gelezen

Last Friday I had a short discussion with a colleague on what the 'best' way was to get data out of the DataReader?

There are a number of options:

Use the name of the column:

<BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px">
SqlDataReader dr = cmd.ExecuteReader();
</BLOCKQUOTE>

<BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px">
while{dr.Read())
{
...
string columnvalue  = dr["au_lname"].ToString();
...
}
</BLOCKQUOTE>

The benefit here is the ease in writing the code and the readability.

 

The second way of approaching the DataReader is using an index:

<BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px">

while{dr.Read())
{
...
string columnvalue  = dr[1].ToString();
...
}
</BLOCKQUOTE>

This code is a bit harder to read, but is should be faster because there's no need to do a lookup on the column-name.

Once an extra column is added to the query, we'll need to go over all of the indices to confirm we didn't break anything.

To verify that this code is actually faster, I created a small test-program that retrieves data from the pubs-database. The table shows the average time to get records from the authors-table into a variable.

<TABLE cellSpacing=0 cellPadding=0 width=207 border=0> <TD vAlign=bottom noWrap width=77>

<FONT size=2>count
---------- </FONT>

</TD> <TD vAlign=bottom noWrap width=65>

<FONT size=2>string
----- </FONT>

</TD> <TD vAlign=bottom noWrap width=65>

<FONT size=2>index
-----</FONT>

</TD> <TD vAlign=bottom noWrap width=77 x:num> <P align=left><FONT size=2>1 </FONT></P></TD> <TD vAlign=bottom noWrap width=65 x:num="1.6765538636893802E-2"> <P align=right><FONT size=2>0.016766 </FONT></P></TD> <TD vAlign=bottom noWrap width=65 x:num="1.37352652362242E-2"> <P align=right><FONT size=2> 0.013735 </FONT></P></TD> <TD vAlign=bottom noWrap width=77 x:num> <P align=left><FONT size=2>10 </FONT></P></TD> <TD vAlign=bottom noWrap width=65 x:num="2.4425450720692199E-3"> <P align=right><FONT size=2>0.002443 </FONT></P></TD> <TD vAlign=bottom noWrap width=65 x:num="1.7078148200399799E-3"> <P align=right><FONT size=2> 0.001708 </FONT></P></TD> <TD vAlign=bottom noWrap width=77 x:num> <P align=left><FONT size=2>100 </FONT></P></TD> <TD vAlign=bottom noWrap width=65 x:num="1.0640681986118299E-3"> <P align=right><FONT size=2>0.001064 </FONT></P></TD> <TD vAlign=bottom noWrap width=65 x:num="4.8499739492030298E-4"> <P align=right><FONT size=2>0.000485 </FONT></P></TD> <TD vAlign=bottom noWrap width=77 x:num> <P align=left><FONT size=2>1000 </FONT></P></TD> <TD vAlign=bottom noWrap width=65 x:num="6.9109761156794895E-4"> <P align=right><FONT size=2>0.000691 </FONT></P></TD> <TD vAlign=bottom noWrap width=65 x:num="3.8279725495838301E-4"> <P align=right><FONT size=2>0.000383 </FONT></P></TD> <TD vAlign=bottom noWrap width=77 x:num> <P align=left><FONT size=2>10000 </FONT></P></TD> <TD vAlign=bottom noWrap width=65 x:num="6.9728644283002404E-4"> <P align=right><FONT size=2>0.000697 </FONT></P></TD> <TD vAlign=bottom noWrap width=65 x:num="3.9660727829933799E-4"> <P align=right><FONT size=2>0.000397 </FONT></P></TD></TABLE>

As you can see, it actually turns out to be faster to use an index.

To get the best of both worlds, you can use a combination of both approaches:

<BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px">
const int FIELD_AUID = 0;
const int FIELD_AU_LNAME = 1;
const int FIELD_AU_FNAME = 2;
...
while{dr.Read())
{
...
string columnvalue  = dr[FIELD_AU_LNAME].ToString();
...
}
</BLOCKQUOTE>

This way changes to the query only require editing of the list of constants.

The performance gain for test-program seems to comparable to changing from the OleDbProvider to SqlClient. So making a small change to the code, has it running about twice as fast.

Categorieën:

Bijgewerkt: