I have an application that builds a SQL statement based on search criteria, and displays the results. The first retrieve runs rather quickly, subsequent searches tend to run very slow. This happens even when the exact same search criteria is used.
One distinct difference between the first search and any subsequent searches is the way the Selects are passed to SQL server by Visual Basic.
In the first search the Select is passed to SQL Server as a straight SQL statement and SQL Server returns streams of large packets. I'm assuming this is the Select that returns the largest amount of data and has the most impact on apparent performance to the user. Subsequent Selects that are still part of the same search are passed as RPCs to 'sp_cursoropen'. The Select statement in this case is passed as a parameter to this stored procedure. The data that's returned is returned in much smaller packets with many other "sp_cursor..." RPCs in-between, no streaming. There are other Selects that are sent as straight SQL towards the end and they will stream.
When the search is executed a 2nd time the primary difference is that the 1st Select sent to SQL server is passed as an RPC to sp_cursoropen. The behavior is then no-streaming with small packets etc. Since this returns the largest chunk of the data it has a big impact on performance and when the user finally sees data on the screen.
I really can't explain this behavior, but based on this I think the application is determining the performance, not the server. Do you know why sometimes it would pass the Selects differently?
I am using recordsets (this is an overview of the connection and recordset creation):
Public m_Connection As ADODB.Connection
Private m_Recordset As ADODB.Recordset
Private strSelect As String
Set m_Connection = New ADODB.Connection
strconnect = "Data Source=DB; Database=DB; UID=" & txtUserID.Text & "; PWD=" & txtPassword.Text & "; SQL_PACKET_SIZE=4096"
m_Connection.ConnectionString = strconnect
m_Connection.CommandTimeout = 0
m_Connection.Open
< code to load a string select statement into strSelect >
m_Recordset.Source = strSelect
m_Recordset.Open
If m_Recordset.State = adStateOpen Then
m_Recordset.Close
End If
One distinct difference between the first search and any subsequent searches is the way the Selects are passed to SQL server by Visual Basic.
In the first search the Select is passed to SQL Server as a straight SQL statement and SQL Server returns streams of large packets. I'm assuming this is the Select that returns the largest amount of data and has the most impact on apparent performance to the user. Subsequent Selects that are still part of the same search are passed as RPCs to 'sp_cursoropen'. The Select statement in this case is passed as a parameter to this stored procedure. The data that's returned is returned in much smaller packets with many other "sp_cursor..." RPCs in-between, no streaming. There are other Selects that are sent as straight SQL towards the end and they will stream.
When the search is executed a 2nd time the primary difference is that the 1st Select sent to SQL server is passed as an RPC to sp_cursoropen. The behavior is then no-streaming with small packets etc. Since this returns the largest chunk of the data it has a big impact on performance and when the user finally sees data on the screen.
I really can't explain this behavior, but based on this I think the application is determining the performance, not the server. Do you know why sometimes it would pass the Selects differently?
I am using recordsets (this is an overview of the connection and recordset creation):
Public m_Connection As ADODB.Connection
Private m_Recordset As ADODB.Recordset
Private strSelect As String
Set m_Connection = New ADODB.Connection
strconnect = "Data Source=DB; Database=DB; UID=" & txtUserID.Text & "; PWD=" & txtPassword.Text & "; SQL_PACKET_SIZE=4096"
m_Connection.ConnectionString = strconnect
m_Connection.CommandTimeout = 0
m_Connection.Open
< code to load a string select statement into strSelect >
m_Recordset.Source = strSelect
m_Recordset.Open
If m_Recordset.State = adStateOpen Then
m_Recordset.Close
End If