Oracle выбирает слишком длинный запрос - PullRequest
3 голосов
/ 04 октября 2011

У нас есть внутреннее приложение на основе .Net, которое вызывает определенные процедуры в Oracle (10g).Один из этих запросов запускается для получения входных / выходных параметров этих процедур.Это довольно простой запрос выбора.Но даже в самых лучших обстоятельствах это занимает 3 секунды.При аренде несколько раз в день это занимает более 40 секунд и приводит к превышению времени ожидания нашего приложения .Net.Запрос на выбор:

SELECT   a.argument_name,
           a.data_type,
           a.in_out,
           NVL (a.data_length, 0) AS data_length,
           NVL (a.data_precision, 0) AS data_precision,
           NVL (a.data_scale, 0) AS data_scale
    FROM   ALL_ARGUMENTS a, all_objects o
   WHERE   o.object_id =
              (SELECT   object_id
                 FROM   all_objects
                WHERE       UPPER (object_name) = UPPER ('resourcemanager_pkg')
                        AND object_type = 'PACKAGE'
                        AND owner = 'OFFICEDBA')
           AND UPPER (a.object_name) = UPPER ('p_search_roles')
           AND a.OBJECT_ID = o.OBJECT_ID
ORDER BY   a.position ASC

Этот запрос возвращает параметры входа / выхода конкретной процедуры.

resourcemanager_pkg - имя пакета, p_search_roles - имя процедуры.Мы вызываем этот запрос для каждого вызова базы данных для процедур.

Что-то не так с этим запросом?Любая помощь будет оценена.Пожалуйста, дайте мне знать, если требуется дополнительная информация.

Спасибо, Vikalp Jain

Ответы [ 5 ]

3 голосов
/ 05 октября 2011

Удалите все вызовы UPPER () в представлении оракула.Они уже в верхнем регистре.Я также переместил запрос имени пакета в «with предложение», чтобы он вызывался один раз.

WITH PACKAGE AS
     (SELECT object_id, owner, object_name NAME
        FROM all_objects
       WHERE object_name = UPPER ('SOME_PACKAGE_NAME')
         AND object_type = 'PACKAGE'
         AND owner = 'SOME_SCHEMA_OWNER_NAME')
SELECT   a.argument_name, a.data_type, a.in_out,
         NVL (a.data_length, 0) AS data_length,
         NVL (a.data_precision, 0) AS data_precision,
         NVL (a.data_scale, 0) AS data_scale
    FROM ALL_ARGUMENTS a, PACKAGE
   WHERE a.package_name = PACKAGE.NAME AND a.owner = PACKAGE.owner
   --This is the 'procedure' name within the package.
   AND a.OBJECT_NAME = 'SOME_PROCEDURE_NAME'
ORDER BY a.POSITION ASC
2 голосов
/ 04 октября 2011

У вас есть возможность изменить сгенерированный запрос? Похоже, что он делает постороннее соединение с таблицей ALL_OBJECTS. Похоже, что ваш запрос эквивалентен этому

SELECT   a.argument_name,
           a.data_type,
           a.in_out,
           NVL (a.data_length, 0) AS data_length,
           NVL (a.data_precision, 0) AS data_precision,
           NVL (a.data_scale, 0) AS data_scale
    FROM   ALL_ARGUMENTS a,
           (SELECT   object_id
              FROM   all_objects
             WHERE       UPPER (object_name) = UPPER ('resourcemanager_pkg')
                     AND object_type = 'PACKAGE'
                     AND owner = 'OFFICEDBA') o
    WHERE  UPPER (a.object_name) = UPPER ('p_search_roles')
      AND  a.OBJECT_ID = o.OBJECT_ID
    ORDER  BY a.position ASC

Я бы также ожидал, что использование ALL_PROCEDURES вместо ALL_OBJECTS для получения OBJECT_ID будет более эффективным.

Вы собрали словарную статистику? Запросы к представлениям словаря данных, как правило, довольно сложно настроить, поскольку вы не можете добавлять индексы или другие структуры, чтобы ускорить процесс. Но, по крайней мере, сбор словарной статистики может дать оптимизатору лучшую информацию, чтобы можно было выбрать лучший план.

Наконец, возможно ли, что вы могли бы материализовать данные из словаря данных в материализованном представлении, которое периодически обновляется, чтобы вы могли индексировать? Это будет означать, что результаты не будут сразу отражать изменения в определении процедур. С другой стороны, вы обычно не хотите вносить изменения в определения процедур в режиме реального времени, и вы всегда можете обновить материализованные представления после внесения изменений в схему.

0 голосов
/ 05 октября 2011

Попробуйте это. Я специально оставил вызовы UPPER, потому что, как упоминалось ранее, это приведет к тому, что индексы не будут использоваться.

SELECT   a.argument_name,
       a.data_type,
       a.in_out,
       NVL (a.data_length, 0) AS data_length,
       NVL (a.data_precision, 0) AS data_precision,
       NVL (a.data_scale, 0) AS data_scale
from all_arguments a
    inner join all_objects o ON o.object_id = a.object_id
where o.object_name = 'resourcemanager_pkg'
    and o.object_type='PACKAGE'
    AND O.OWNER = 'OFFICEDBA'
    AND A.OBJECT_NAME='p_search_roles'
ORDER BY   a.position ASC
0 голосов
/ 04 октября 2011

Проблему производительности базы данных, как правило, трудно решить, взглянув на сам запрос.

Вот несколько простых шагов, которые необходимо выполнить для диагностики проблемы

  • explain plan, это скажет вам, где ваш запрос медленный
  • Проверьте ваши индексы, есть ли у вас индекс по UPPER(object_name)?
  • Проверьте свою статистику, актуально ли это?
0 голосов
/ 04 октября 2011

Вам действительно следует рассмотреть возможность мониторинга вашей базы данных с помощью Oracle Enterprise Manager. Это достаточно удобное веб-приложение, которое профилирует все ваши запросы и быстро расскажет вам, почему вы работаете медленно. Подробнее см. На веб-сайте Oracle.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...