Oracle 9i - Проблемы оптимизатора с арифметикой дат? - PullRequest
2 голосов
/ 08 августа 2011

У нас есть запрос, который включает (но имеет другие объединения, таблицы и условия):

SELECT
    o.contact_id, 
    o.completed_date, 
    o.submitted_date
FROM
    orders o /* 860,000 row table */
WHERE   
    ? <= o.submitted_date
    AND o.submitted_date < ? + 1

, вызываемый из приложения Java.

Параметры ? позволяют проверять наличиезаказы, отправленные между двумя датами.

Однако этот запрос выполняется очень медленно.

Мы преобразовали для запуска из PL / SQL для тестирования следующим образом:

SubmittedDateFrom date:=to_date('2011-07-15', 'yyyy-mm-dd');
SubmittedDateTo date:=to_date('2011-07-15', 'yyyy-mm-dd');
CURSOR c_orgs    IS    
SELECT
    o.contact_id, 
    o.completed_date, 
    o.submitted_date
FROM
    orders o
WHERE   
    SubmittedDateFrom <= o.submitted_date
    AND o.submitted_date < SubmittedDateTo + 1;
BEGIN
    FOR c_o IN c_orgs LOOP
        DBMS_OUTPUT.put_line('Submitted date = '||c_o.submitted_date);                               
    END LOOP;
END;

ЕСЛИ мылибо:

  1. преобразовать значение SubmittedDateTo в to_date('2011-07-16', 'yyyy-mm-dd') (т.е. выполнить арифметику вне запроса),
  2. сделать SubmittedDateTo строкой и использовать "to_date('SubmittedDateTo', 'yyyy-mm-dd') +1 "как второе условие в WHERE.

THEN, запрос резко ускоряется (<1 секунда против 44+ секунд). </p>

Дополнительная информация:

  • при выполнении плана объяснения для запроса выдается ошибка ORA-00932: inconsistent datatypes: expected DATE got NUMBER
  • столбец submitted_date имеет индекс, а статистика и т. Д. Были выполнены
  • , заключая в оболочкуSubmittedDateTo + 1 при вызове trunc() не влияет на производительность
  • У нас нет базы данных не-9i с аналогичными объемами данных и т. Д.проверьте, является ли это версией Oracle или нет.

Вопрос в том, что мы не можем найти какую-либо информацию, в которой четко указано, что в Oracle 9i Optimizer есть проблема с такой арифметикой дат.Это то, что здесь происходит, или что-то еще происходит?

Ответы [ 2 ]

1 голос
/ 08 августа 2011

Согласно документации Oracle (это v10, но я полагаю, что это относится и к 9i), "... не поддерживает EXPLAIN PLAN для операторов, выполняющих неявное преобразование типов переменных связывания даты. «

Помимо подхода, предложенного Олли, вы пытались использовать trunc () соотв. вместо этого?

SELECT
    o.contact_id, 
    o.completed_date, 
    o.submitted_date
FROM
    orders o /* 860,000 row table */
WHERE   
    trunc(o.submitted_date) = trunc(?)

соответственно.

SELECT
    o.contact_id, 
    o.completed_date, 
    o.submitted_date
FROM
    orders o /* 860,000 row table */
WHERE   
    o.submitted_date between ? and ? + 1
1 голос
/ 08 августа 2011

Я бы всегда гарантировал, что все преобразования обрабатываются явно (и предполагая, что o.submitted_date является типом данных DATE):

DECLARE
  CURSOR c_orgs    
  IS
     SELECT o.contact_id,      
            o.completed_date,
            o.submitted_date 
       FROM orders o 
      WHERE o.submitted_date BETWEEN TO_DATE(SubmittedDateFrom, 'yyyy-mm-dd') 
                                 AND TO_DATE(SubmittedDateTo, 'yyyy-mm-dd'); 
BEGIN
   FOR c_o IN c_orgs 
   LOOP
      DBMS_OUTPUT.put_line('Submitted date = '||c_o.submitted_date);
   END LOOP;
END; 

Это гарантирует, что в каких-либо неявных преобразованиях нет ошибок, и все преобразования очевидны в их типе данных.

"Вопрос в том, что мы не можем найти какую-либо информацию, в которой четко указано, что в оптимизаторе Oracle 9i есть проблема с такой арифметикой дат. Это то, что здесь происходит или происходит что-то еще?"

Я не думаю, что это оптимизатор, это может быть конечный продукт ваших неявных преобразований, вызывающих проблемы с производительностью. Поскольку у вас нет настроек NLS для дат и т. Д. Из базы данных Oracle, трудно сказать, но если использование явных преобразований повышает производительность, я бы посоветовал вам их использовать (и это тоже лучше).

Надеюсь, это поможет, Олли.

...