Процедура Oracle работает медленно в ASP, но быстро в TOAD

У меня возникла эта проблема с процедурой ниже. Это довольно быстро, когда я запускаю его в TOAD для Oracle. Но когда он вызывается из моего приложения asp, для возврата данных действительно требуется много времени.

Любая помощь приветствуется.

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;

person Tiger    schedule 30.07.2014    source источник
comment
может это часть? stackoverflow.com/questions/3655399/   -  person Kritner    schedule 30.07.2014
comment
@Kritner Спасибо. Я посмотрю.   -  person Tiger    schedule 30.07.2014
comment
Какой адаптер вы используете? Вы случайно не используете System.Data.OracleClient?   -  person Hambone    schedule 30.07.2014
comment
@Hambone Да, я использую System.Data.OracleClient и должен использовать это. Адаптер — OracleDataAdapter.   -  person Tiger    schedule 31.07.2014
comment
System.Data.OracleClient проблематичен. Переключитесь на ODP.net (или управляемый ODP.net), и я готов поспорить на доллар, что ваши проблемы исчезнут.   -  person Hambone    schedule 31.07.2014
comment
@Hambone спасибо за совет. Мой начальник упрямится, что не хочет переходить на новый модуль. Мне нужно немного поработать, чтобы сделать это.   -  person Tiger    schedule 01.08.2014
comment
У меня есть предложение. Смоделируйте тестовый проект, который вставляет 50 000 строк в новую таблицу. Имейте одну версию, которая делает это в System.Data.OracleClient, одну, которая делает это с ODP.net, и одну, которая делает это с ODP.net, используя массовые вставки (невозможно в драйвере Microsoft, поскольку он не поддерживает OCI). У него голова свалится с шеи, когда он увидит результаты. Если бы вы могли каким-то образом показать ему статистику по базе данных Oracle, это было бы восхитительно.   -  person Hambone    schedule 01.08.2014


Ответы (1)


Я знаю, что это звучит как чрезмерное упрощение, но вам нужно переключиться на неустаревший драйвер Oracle. Последний раз System.Data.OracleClient был упакован с .NET 2.0, и даже Microsoft говорит использовать ODP.net. Также есть управляемые ODP.net и devArt dotConnect, работа которых не зависит от локального клиента Oracle.

Вы, вероятно, думаете, что это не объясняет задержку, и я признаюсь, что не устанавливал и не тестировал вашу процедуру, но я могу поделиться с вами этим опытом.

Примерно в 2008 году у нас был простой запрос, он отлично работал как с System.Data.OracleClient, так и с ODP.net. Однако, когда мы добавили в запрос параметр (переменную связывания), запрос ODP.net выполнился нормально — в мгновение ока, но версия Microsoft имела необъяснимую 17-секундную задержку при «выполнении» (ExecuteDataReader) фаза. При переключении на литерал все пошло нормально.

Переменные связывания приветствуются и на самом деле должны повышать производительность, но в данном случае это вредно. Это не имело смысла. Мы обнаружили, что это верно и в других ситуациях. Это не всегда было 17 секунд, но это всегда было необъяснимо.

ПОПРОБУЙТЕ использовать вместо этого ODP.net, и если это не сработает, я съем свою шляпу.

Вы упомянули, что вам нужно использовать драйвер Microsoft ... можете ли вы объяснить?

-- РЕДАКТИРОВАТЬ --

Это использует литерал:

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();
}

Вы передаете буквальное значение в запросе, который, в свою очередь, каждый раз становится новым запросом к Oracle — он должен анализировать и компилировать его перед выполнением.

Это использует переменную связывания:

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 — переменная связывания.

Оператор анализируется один раз, один раз компилируется и выполняется несколько раз с разными значениями. Это намного эффективнее и удобнее для общего пула (и, следовательно, для всех других пользователей этой базы данных).

person Hambone    schedule 31.07.2014
comment
мой тоже был 17 секунд. и это было, когда он запустил адаптер данных оракула и когда попытался заполнить его набором данных, который вернулся из процедуры пакета оракула. и ты был прав, это всегда необъяснимо. что вы подразумеваете под переменными связывания? - person Tiger; 01.08.2014
comment
Объяснение переменных связывания было слишком длинным, чтобы опубликовать его в комментарии — я отредактировал сообщение. Когда я использую переменные связывания, System.Data.OracleClient сходит с ума. Когда я использую литералы, это нормально (но это приводит к перегрузке общего пула и, как правило, является плохой практикой). Какие проблемы возникнут при переходе на Oracle ODP.net? - person Hambone; 01.08.2014