473,587 Members | 2,487 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Performance problems with StoredProcedure in Web application

Hi,
imagine there's a WEB application reading data from an Oracle database
to visualize in using DataGrids in the clients browser. Yes, sounds
simple, just create OracleConnectio n + OracleCommand + DataAdapter,
bind a DataGrid to the DataAdapter, that's it.

Problem with that approach might be the hardcoded CommandString of the
OracleCommand. Whenever somebody requests query string changes you have
to adapt the C# code, to recompile and test your application, and last
but not least to deploy the new version to one or more servers.

To solve that the decision was made to create a StoredProcedure
containing the SQL CommandString, in case of query to be changed the
procedure independently from the C# application may be adapted.

Allright, after creating the StoredProcedure I adapted the C# code, so
that instead of the priviously used hardcoded query string of type
CommandType.Tex t the corresponding stored procedure of type
CommandType.Sto redProcedure will be called. The procedure itself
supports a ReferenceCursor , which I bound to the return DataTable. No
big deal, in general it works.

BUT - THE PERFORMANCE:
Where the Text query took approx. 10s, the StoredProcedure took up to 2
minutes to return as the same data!
Does anybody have an idea what might be the reason for that behaviour?

Really appreciate your help - Frank

PS: Finaly two snapshots of the code, first the fast hardcoded version,
second the stored procedure based one:

[OLD]
dwhConnection.C onnectionString =(String)getSes sionObject("dwh ConnectionStrin g");
generalDataAdap ter.SelectComma nd.CommandText= "SELECT * FROM MYTABLE";
DataTable dataGridInputTa ble=new DataTable("gene ral");
generalDataAdap ter.Fill(dataGr idInputTable);
generalAdapter. Fill(dataGridIn putTable);

[NEW]
OracleConnectio n oraConnection=n ew
OracleConnectio n((String)getSe ssionObject("or aConnectionStri ng"));
OracleCommand generalQuery=ne w
OracleCommand(" expt.expt_repor ts_pkg.getAllEx periments",
oraConnection);
generalQuery.Co mmandType=Comma ndType.StoredPr ocedure;
generalQuery.Pa rameters.Clear( );
generalQuery.Pa rameters.Add(ne w OracleParameter ("M_CURSOR",
OracleType.Curs or));
generalQuery.Pa rameters["M_CURSOR"].Direction=Para meterDirection. Output;
OracleDataAdapt er currentAdapter= new OracleDataAdapt er(generalQuery );
DataTable dataGridInputTa ble=new DataTable("gene ral");
currentAdapter. Fill(dataGridIn putTable);

Oct 11 '06 #1
9 2200
Hi Frank,

I appreciate the background info.

<snip>
BUT - THE PERFORMANCE:
Where the Text query took approx. 10s, the StoredProcedure took up to 2
minutes to return as the same data!
Does anybody have an idea what might be the reason for that behaviour?
It's probably the fault of the cursor. Any particular reason why you need the cursor? It's not being used by the textual query.
Really appreciate your help - Frank

PS: Finaly two snapshots of the code, first the fast hardcoded version,
second the stored procedure based one:

[OLD]
dwhConnection.C onnectionString =(String)getSes sionObject("dwh ConnectionStrin g");
generalDataAdap ter.SelectComma nd.CommandText= "SELECT * FROM MYTABLE";
DataTable dataGridInputTa ble=new DataTable("gene ral");
generalDataAdap ter.Fill(dataGr idInputTable);
generalAdapter. Fill(dataGridIn putTable);
Stored procedures will commonly out-perform textual queries when selecting data, so I'd imagine that in stress situations the above
might perform worse then a stored procedure that does the same exact thing, but I doubt the opposite will ever be true.
[NEW]
OracleConnectio n oraConnection=n ew
OracleConnectio n((String)getSe ssionObject("or aConnectionStri ng"));
OracleCommand generalQuery=ne w
OracleCommand(" expt.expt_repor ts_pkg.getAllEx periments",
oraConnection);
generalQuery.Co mmandType=Comma ndType.StoredPr ocedure;
generalQuery.Pa rameters.Clear( );
generalQuery.Pa rameters.Add(ne w OracleParameter ("M_CURSOR",
OracleType.Curs or));
generalQuery.Pa rameters["M_CURSOR"].Direction=Para meterDirection. Output;
OracleDataAdapt er currentAdapter= new OracleDataAdapt er(generalQuery );
DataTable dataGridInputTa ble=new DataTable("gene ral");
currentAdapter. Fill(dataGridIn putTable);
Stored procedures are much safer to use because they're not susceptible to SQL injection attacks, where the user submits data in the
query string, for example, such as ""frank' OR 1=1) timedelay...". The exception is, of course, when executing dynamic SQL in your
stored procedures. I only mention this because of the background you supplied and how it sounded much more complex then your
example "SELECT * FROM MYTABLE", and the code above that executes the stored procedure. i.e., In your code examples you aren't
dealing with parameters but you seemed to imply that you use them.

I suggest keeping the procedure and removing the cursor to see if that helps.

--
Dave Sexton
Oct 11 '06 #2
Thank you Dave,

In general I'm with you regarding keeping the stored procedure (dynamic
SQL is not necessary) and to remove the REF_CURSOR.

But honestly this cursor is the only option I'm familiar with to return
multiple data records, each containing several column values itself.

So what are the alternatives? How to return a data table/data matrix
containing query results from a stored procedure?

Regards - Frank

Oct 11 '06 #3
Hi Frank,

I'm not really sure I understand your question so I'll try to address both possibilities, as I see them.

I'm not familiar with Oracle so I don't know if there is any alternative to using a cursor when returning multiple rows, but I must
assume that it's not your only option. And anyway, I really don't see how your second code sample could possibly work but since I'm
not familiar with Oracle I just had to assume that you know what your doing :)

If you are returning multiple result sets then you can use table mappings. The adapter recognizes each table in the result set with
a constant naming convention:

Table
Table1
Table2
Table3
....

So you can use the DataTableMappin gsCollection (via the TableMappings property) to map each table in the result set to the DataTable
that the adapter must fill:

Table dtParentTable
Table1 dtChildTable
Table2 dtAnotherRelate dTable
....

You must determine the order in which you will return each result set from the procedure and then code the TableMappings to reflect
your choice by adding a single DataTableMappin g for each table in the result set:

adapter.TableMa ppings.Add("Tab le", "dtParentTable" );
adapter.TableMa ppings.Add("Tab le1", "dtChildTable") ;
adapter.TableMa ppings.Add("Tab le2", "dtAnotherRelat edTable");
Using DataTableMappin gs and DataColumnMappi ngs on MSDN:
http://msdn.microsoft.com/library/de...mnMappings.asp

(Ignore the first example in the link I posted because it's confusing and doesn't illustrate the common use of the Add method. Once
you understand how mappings work, then I suggest you review the first illustration again to see how mappings can be used in a manner
that alleviates the need for the constant naming convention used by DataAdapters. i.e. Table, Table1, Table2, becomes unnecessary.
:)

--
Dave Sexton

"Frank" <fr***********@ infineon.comwro te in message news:11******** **************@ e3g2000cwe.goog legroups.com...
Thank you Dave,

In general I'm with you regarding keeping the stored procedure (dynamic
SQL is not necessary) and to remove the REF_CURSOR.

But honestly this cursor is the only option I'm familiar with to return
multiple data records, each containing several column values itself.

So what are the alternatives? How to return a data table/data matrix
containing query results from a stored procedure?

Regards - Frank

Oct 11 '06 #4
Hi Frank,

Have you tried executing your query and SP using SQL-Plus to see the
difference in execution time ?

Oct 11 '06 #5
Hi Frank,

Actually, you could probably just ignore my comments about stored procedure performance as compared to textual queries because they
were based solely on my knowledge of SQL Server, not Oracle.

As for your question about how to avoid using a cursor (as I suggested was possible in Oracle) read the following paragraph for more
information.

Here's a section of the documentation from the MSDN topic on the OracleDataAdapt er class:

The .NET Framework Data Provider for Oracle does not support batched SQL statements. However, it does allow you to use multiple REF
CURSOR output parameters to fill a DataSet, each in its own DataTable. You must define the parameters, mark them as output
parameters, and indicate that they are REF CURSOR data types. Note that you cannot use the Update method when the OracleDataAdapt er
is filled using REF CURSOR parameters returned by a stored procedure, because Oracle does not provide the information necessary to
determine what the table name and column names are when the SQL statement is executed.

OracleDataAdapt er on MSDN:
http://msdn2.microsoft.com/en-us/lib...taadapter.aspx

At this point I'm not even sure how TableMappings could be useful to you. Sorry if I made you more confused ;)

--
Dave Sexton

"Dave Sexton" <dave@jwa[remove.this]online.comwrote in message news:uh******** ******@TK2MSFTN GP02.phx.gbl...
Hi Frank,

I'm not really sure I understand your question so I'll try to address both possibilities, as I see them.

I'm not familiar with Oracle so I don't know if there is any alternative to using a cursor when returning multiple rows, but I
must assume that it's not your only option. And anyway, I really don't see how your second code sample could possibly work but
since I'm not familiar with Oracle I just had to assume that you know what your doing :)

If you are returning multiple result sets then you can use table mappings. The adapter recognizes each table in the result set
with a constant naming convention:

Table
Table1
Table2
Table3
...

So you can use the DataTableMappin gsCollection (via the TableMappings property) to map each table in the result set to the
DataTable that the adapter must fill:

Table dtParentTable
Table1 dtChildTable
Table2 dtAnotherRelate dTable
...

You must determine the order in which you will return each result set from the procedure and then code the TableMappings to
reflect your choice by adding a single DataTableMappin g for each table in the result set:

adapter.TableMa ppings.Add("Tab le", "dtParentTable" );
adapter.TableMa ppings.Add("Tab le1", "dtChildTable") ;
adapter.TableMa ppings.Add("Tab le2", "dtAnotherRelat edTable");
Using DataTableMappin gs and DataColumnMappi ngs on MSDN:
http://msdn.microsoft.com/library/de...mnMappings.asp

(Ignore the first example in the link I posted because it's confusing and doesn't illustrate the common use of the Add method.
Once you understand how mappings work, then I suggest you review the first illustration again to see how mappings can be used in a
manner that alleviates the need for the constant naming convention used by DataAdapters. i.e. Table, Table1, Table2, becomes
unnecessary. :)

--
Dave Sexton

"Frank" <fr***********@ infineon.comwro te in message news:11******** **************@ e3g2000cwe.goog legroups.com...
>Thank you Dave,

In general I'm with you regarding keeping the stored procedure (dynamic
SQL is not necessary) and to remove the REF_CURSOR.

But honestly this cursor is the only option I'm familiar with to return
multiple data records, each containing several column values itself.

So what are the alternatives? How to return a data table/data matrix
containing query results from a stored procedure?

Regards - Frank


Oct 11 '06 #6
Hi Dave,

the MSDN article you're referring to describes in detail the current
status of my source code. As mentioned the SQL select statement has
been encapsulated in a StoredProcedure , which returns results via
REF_CURSOR. Afterwards the C# code has been adapted as described in the
article.
Technically that works, but accessing data via STORED_PROCEDUR E instead
of the previously used (identic) SELECT statement takes 10 times
longer. Of course this is not acceptable, especially for a WEB
application.

So unfortunately I still do not know the reason for this performance
difference, as mentioned select statement and volume of retrieved data
both are identical.

Thanks anyway, Frank

Oct 12 '06 #7
Hi Frank,

Well you haven't made it clear to me whether you are trying to select multiple result sets (tables) or just a single result set
(table) with multiple rows. The article made it seem like Oracle provides a way to do the latter without cursors, which I assume
will increase the performance of your application. That's just an assumption however since the article doesn't mention anything
about selecting only a single result set.

I suggest that you do further research on Oracle to find out if you can do the same thing you are trying to do now but without
cursors, because I still believe that cursors are the source of the degradation in performance that you have observed based on my
experience with SQL Server.

GL

--
Dave Sexton

"Frank" <fr***********@ infineon.comwro te in message news:11******** **************@ b28g2000cwb.goo glegroups.com.. .
Hi Dave,

the MSDN article you're referring to describes in detail the current
status of my source code. As mentioned the SQL select statement has
been encapsulated in a StoredProcedure , which returns results via
REF_CURSOR. Afterwards the C# code has been adapted as described in the
article.
Technically that works, but accessing data via STORED_PROCEDUR E instead
of the previously used (identic) SELECT statement takes 10 times
longer. Of course this is not acceptable, especially for a WEB
application.

So unfortunately I still do not know the reason for this performance
difference, as mentioned select statement and volume of retrieved data
both are identical.

Thanks anyway, Frank

Oct 12 '06 #8
...well, thanks for all the answers,
but instead of the suspicious RefCursor within the StoredProcedure the
query itself was the performance killer. There was only one additional
column to be accessed via the StoredProcedure , which slowed done
everything.

Finally I'm very happy with the RefCursor, works really fine and fast.

Frank

Lessons learned: Never trust a colleague telling you "query A is as the
same as query B" without checking yourself :-)

Oct 19 '06 #9
Hi Frank,

Thanks for the follow-up. (I'll be sure to keep my "mouth" shut when Oracle questions pop up in the future.)

--
Dave Sexton

"Frank" <fr***********@ infineon.comwro te in message news:11******** *************@m 7g2000cwm.googl egroups.com...
..well, thanks for all the answers,
but instead of the suspicious RefCursor within the StoredProcedure the
query itself was the performance killer. There was only one additional
column to be accessed via the StoredProcedure , which slowed done
everything.

Finally I'm very happy with the RefCursor, works really fine and fast.

Frank

Lessons learned: Never trust a colleague telling you "query A is as the
same as query B" without checking yourself :-)

Oct 19 '06 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

5
4021
by: nmac | last post by:
Hi all, hopefully someone can offer some sagely advice regarding Production use of Jakarta's Tomcat. First, some brief background. My company have a servlet application that connects to a MySQL database. The servlet is deployed on two seperate win2k servers (Access to the tomcat servers is via DNS round robin load balancing). The database is on a another win2k server.
5
3991
by: Scott | last post by:
I have a customer that had developed an Access97 application to track their business information. The application grew significantly and they used the Upsizing Wizard to move the tables to SQL 2000. Of course there were no modifications made to the queries and they noticed significant performance issues. They recently upgraded the application to Access XP expecting the newer version to provide performance benefits and now queries take...
24
2762
by: Bob Alston | last post by:
Most of my Access database implementations have been fairly small in terms of data volume and number of concurrent users. So far I haven't had performance issues to worry about. <knock on wood> But I am curious about what techniques those of you who have done higher volume access implementations use to ensure high performance of the database in a multi-user 100mbps LAN implementation??? Thanks
4
3353
by: Martin | last post by:
I am using graphics as backgrounds for forms,buttons,labels etc. The question is: is it faster to load all graphics from files on app start or to use it embeded (places in editor during design). Reason for my question is that application has 5mb, while without graphics it has cca 400kb. Graphic files (bmps) take about 200kb (in program, they are repeated many times, ie almost all labels (around 200) have same background image)). Also,...
9
3313
by: Mike L | last post by:
I tried a sample of code in MSDN magazine, but now I'm stuck. What code has the best performance to populate a Data Grid with a SP? Below is the code I have, which might be completing the wrong way to populate a data grid. I like using code and not the server explorer. (I replaced the sa password for this post.) private void frmDealerSearch_Load(object sender, System.EventArgs e) { string sConnString = "Data
6
7067
by: tfsmag | last post by:
I have a Grid that I've set up to have two of the fields use dropdownlists while in edit mode. Now I can bind the data to the dropdownlists just fine. My problem is that the second dropdown depends on the first dropdown to pass a parameter to it. If I have a selectedvalue set to the second drop down, when i select a new value from the first drop down it gives me this error. "Databinding methods such as Eval(), XPath(), and Bind() can...
1
2442
by: jvn | last post by:
I am experiencing a particular problem with performance counters. I have created a set of classes, that uses System.Diagnostics.PerformanceCounter to increment custom performance counters (using .Net 2.0) The performance counter categories have been successfully created. When the set of classes are used by a WinForm test harness application, they function as expected, and the performance counters can be seen to be updated by using the...
2
1262
by: Chris | last post by:
We have an asp application some of which will be being ported over to asp.net so this may be a little OT. It is having some bad performance problems and we need to isolate which areas are causing the problems. The main performance problems are database related i.e. timeouts and deadlocks Some questions: Microsoft's ACT. How is it better than the Web Stress Application Tool? Is ACT purely .net or can be used to look at any web app. What...
0
1131
by: Chris | last post by:
We have an asp application some of which will be being ported over to asp.net so this may be a little OT. It is having some bad performance problems and we need to isolate which areas are causing the problems. The main performance problems are database related i.e. timeouts and deadlocks Some questions: Microsoft's ACT. How is it better than the Web Stress Application Tool? Is ACT purely .net or can be used to look at any web app. What...
0
7923
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
7852
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
8216
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
8221
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
6629
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
5719
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
3845
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
1
1455
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
1192
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.