Динамические подсказки в Oracle

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

Я хотел бы сделать это:

PROCEDURE PROCESS_STEP_1 (p_cust_id NUMBER)
IS
  v_hint_value NUMBER;
BEGIN
  -- Select correct value from param table
  SELECT value INTO v_hint_value
    FROM param_table
    WHERE cust_id = p_cust_id
      AND process_name = 'PROCESS_STEP_1';

  INSERT INTO result_table  
  SELECT /*+ PARALLEL v_hint_value */ * FROM etc.

END;

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

У вас есть идеи, как что-то подобное можно реализовать? Спасибо!

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
435
1

Ответы 1

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

Тем не менее, у Oracle есть функция перевода SQL. Он предназначен для того, чтобы вы могли переводить SQL-запросы из приложений, написанных для баз данных, отличных от Oracle, но он также может служить вашей цели. Что вы хотите сделать, так это использовать эту функцию для «перевода» подсказок в любом входящем операторе SQL до того, как Oracle его проанализирует.

Вот пример кода, чтобы проиллюстрировать концепцию и начать работу. Опять же - я не рекомендую это, но SO - это место для ответов, а не лекций, так что вот оно...

Шаг 1. Убедитесь, что у вас есть соответствующие права.

-- GRANT CREATE ANY SQL TRANSLATION PROFILE TO yourapplication
-- GRANT TRANSLATE ANY SQL TO yourapplication
-- GRANT USE ANY SQL TRANSLATION PROFLE TO yourapplication
-- GRANT EXECUTE ON SYS.DBMS_SQL_TRANSLATOR TO yourapplication

Создайте таблицу для хранения переводов подсказок

Идея здесь заключается в том, что вы встраиваете подсказки в свое приложение, например «/+ ПОДСКАЗКА12345/», и что вы будете заполнять эту таблицу по-разному на каждом сайте клиента. Очевидно, что вы можете сделать что-то более сложное.

CREATE TABLE myapp_hint_translations ( hint_id VARCHAR2(80), hint_text VARCHAR2(800) );

INSERT INTO myapp_hint_translations VALUES ( '/*+HINT12345*/','/*+PARALLEL(4)*/');

COMMIT;

Создайте пакет PL/SQL для выполнения перевода подсказки.

Вы должны использовать имена процедур и параметры как указано. Они требуются пакет DBMS_SQL_TRANSLATOR, который мы будем использовать.

CREATE OR REPLACE PACKAGE myapp_hint_translator IS
  PROCEDURE translate_sql( sql_text IN CLOB, 
                           translated_text OUT CLOB );

  PROCEDURE translate_error( error_code IN BINARY_INTEGER,
                             translated_code OUT BINARY_INTEGER,
                             translated_sqlstate OUT VARCHAR2 );

END myapp_hint_translator;
/

CREATE OR REPLACE PACKAGE BODY myapp_hint_translator IS
  PROCEDURE translate_sql( sql_text IN CLOB, 
                           translated_text OUT CLOB ) IS
  BEGIN
    <<hint_search>>
    FOR r IN ( SELECT hint_id, hint_text FROM myapp_hint_translations ) LOOP
      IF INSTR(sql_text, r.hint_id ) > 0 THEN
        translated_text := replace(sql_text,r.hint_id,r.hint_text);
        RETURN;
      END IF;
    END LOOP;
    -- No translation made
    translated_text := sql_text;
  END translate_sql;

  PROCEDURE translate_error( error_code IN BINARY_INTEGER,
                             translated_code OUT BINARY_INTEGER,
                             translated_sqlstate OUT VARCHAR2 ) IS
  BEGIN
    -- We are not using this feature
    NULL;
  END;

END myapp_hint_translator;

Сообщите Oracle, чтобы начать использовать наш переводчик

BEGIN
  dbms_sql_translator.create_profile(profile_name => 'MYAPP');
  dbms_sql_translator.set_attribute(profile_name => 'MYAPP',
                                    attribute_name => dbms_sql_translator.attr_translator,
                                    attribute_value => 'myappschema.myapp_hint_translator');
END;

ALTER SESSION SET SQL_TRANSLATION_PROFILE=MYAPP;

ALTER SESSION SET EVENTS = '10601 trace name context forever, level 32';

-- Test some of your application and verify hints are being translated

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

duffmansk 29.03.2019 16:56

Если вы можете исправить это с помощью подсказки, вы можете исправить это с помощью варианта того, что я опубликовал. Возможно, вам придется каким-то образом удалить SQL-запросы из библиотечного кеша, чтобы заставить их повторно анализировать. Опять же, вся эта идея звучит плохо для меня.

Matthew McPeak 29.03.2019 17:22

Существует множество настроек уровня базы данных и уровня сеанса для контроля или ограничения степени параллелизма (DOP) или «автоматической» степени для указания Oracle вычислить наилучший DOP. Те не работают? Возможно, вы захотите опубликовать отдельный вопрос конкретно о динамической настройке DOP для ваших запросов, поскольку он сильно отличается от вашего сообщения о динамическом изменении подсказок.

Matthew McPeak 29.03.2019 17:22

Другие вопросы по теме