0

I am having this issue with the procedure below. It's pretty fast when I run it in TOAD for Oracle. But when it's being called from my asp application, it's really taking a long time to return the data.

Any help is appreciated.

PROCEDURE Getdruminfo --get list of drums details
                     (
  Pvessel_id               Ccmsdba.Barcode.Vessel_id%TYPE,
  Pbarcode_status_id       CCMSDBA.BARCODE.BARCODE_STATUS_ID%TYPE,
  Pagingfrom               INTEGER,
  Pagingto                 INTEGER,
  Pdrum_type               VARCHAR2,
  Plocation_id             CCMSDBA.LOCATION.LOCATION_ID%TYPE,
  Pgroup_by                VARCHAR2,
  Sa_return            OUT Ref_cv_type
)
IS
BEGIN
  IF Pgroup_by IS NOT NULL
  THEN
     IF Pgroup_by = 'BARCODE_STATUS_ID'
     THEN
        BEGIN
           OPEN Sa_return FOR
                SELECT COUNT (*) AS COUNT,
                       Bdd.Aging_cat_min_days AS Aging,
                       Bdd.Status AS Category,
                       Bdd.Barcode_status_id AS Id
                  FROM Ccmsdba.Vw_barcode_drilldown_drum Bdd
                 WHERE Bdd.Location_id =
                          NVL (Plocation_id, Bdd.Location_id)
                       AND Bdd.Aging <= NVL (Pagingto, Bdd.Aging)
                       AND Bdd.Aging >= NVL (Pagingfrom, Bdd.Aging)
                       AND Bdd.Drum_type = NVL (Pdrum_type, Bdd.Drum_type)
                       AND Bdd.Barcode_status_id =
                              NVL (Pbarcode_status_id,
                                   Bdd.Barcode_status_id)
                       AND Bdd.Vessel_id = NVL (Pvessel_id, Bdd.Vessel_id)
              GROUP BY Bdd.Status,
                       Bdd.Aging_cat_min_days,
                       Bdd.Barcode_status_id
              ORDER BY Bdd.Aging_cat_min_days;
        END;
Tiger
  • 139
  • 1
  • 3
  • 12
  • could this be part of it? http://stackoverflow.com/questions/3655399/oracle-query-is-slow-or-fails-from-net-app-but-is-fast-from-sql-developer – Kritner Jul 30 '14 at 15:37
  • What adapter are you using? You're not using System.Data.OracleClient, by chance, are you? – Hambone Jul 30 '14 at 17:44
  • @Hambone Yes i am using System.Data.OracleClient and have to use that. The adapter is OracleDataAdapter. – Tiger Jul 30 '14 at 20:55
  • System.Data.OracleClient is problematic. Switch to ODP.net (or managed ODP.net) and I'll bet a dollar your issues will go away. – Hambone Jul 31 '14 at 01:00
  • @Hambone thanks for your advice. My boss is stubborn that he does not want to switch to new module. I need some work around to get this done. – Tiger Aug 01 '14 at 03:00
  • I have a suggestion. Mock up a test project that inserts 50,000 rows into a new table. Have one version that does it in System.Data.OracleClient, one that does it with ODP.net, and one that does it with ODP.net using bulk inserts (not possible in the Microsoft driver because it does not support OCI). His head will fall off of his neck when he sees the results. If you could somehow show him the stats on the Oracle DB, that would be gravy. – Hambone Aug 01 '14 at 11:41

1 Answers1

0

I know this sounds like an oversimplification, but you need to switch to a non-depricated Oracle driver. System.Data.OracleClient was last packaged with .NET 2.0, and even Microsoft says to use ODP.net. There is also managed ODP.net and devArt dotConnect with don't rely on a local Oracle client to work.

You're probably thinking this won't account for the delay, and I confess I haven't set up and tested your procedure, but I can share this experience with you.

Circa 2008 or so, we had a simple query, it ran fine with both System.Data.OracleClient and ODP.net. However, when we added a parameter (bind variable) to the query, the ODP.net query ran normally -- in the blink of an eye, but the Microsoft version had an inexplicable 17-second delay on the "execute" (ExecuteDataReader) phase. When switched to a literal, everything ran fine.

Bind variables are encouraged and should actually help performance, but in this case it hurt. It made no sense. We found this to be true in other situations. It wasn't always 17 seconds, but it was always inexplicable.

TRY using ODP.net instead, and if it doesn't work, I'll eat my hat.

You mentioned that you have to use the Microsoft driver... can you explain?

-- EDIT --

This is using a literal:

string sql = "insert into foo values ({0})";
OracleCommand cmd = new OracleCommand(String.Empty, connection);
foreach (string value in values)
{
    cmd.CommandText = string.Format(sql, value);
    cmd.ExecuteNonQuery();
}

You are passing the literal value in a query, which in turn becomes a new query to Oracle every time -- it has to parse and compile it before it executes.

This is using a bind variable:

OracleCommand cmd = new OracleCommand("insert into foo values (:BAR)",
    connection);
cmd.Parameters.Add(new OracleParameter("BAR", DbType.String));

foreach (string value in values)
{
    cmd.Parameters[0].Value = value;
    cmd.ExecuteNonQuery();
}

:BAR is the bind variable.

The statement is parsed once, compiled once and executed multiple times with different values. It's much more efficient and more friendly to the shared pool (and therefore all other users of this database).

Hambone
  • 15,600
  • 8
  • 46
  • 69
  • mine was 17 seconds too. and it was when it ran to oracle data adapter and when it tried to fill it with data set that returned from the oracle package procedure. and you were right, it's always inexplicable. what do you mean by "bind variables"? – Tiger Aug 01 '14 at 03:07
  • Explanation of bind variables was too long to post in a comment -- I edited the post. When I use bind variables, System.Data.OracleClient goes nuts. When I use literals, it's fine (but it thrashes the shared pool and is generally a bad practice). What would be your issues with switching to Oracle's ODP.net? – Hambone Aug 01 '14 at 11:38