2014-10-06 12 views
0

Это запрос, я бегу:Oracle игнорирует подсказку для индекса с синонимов и 2 просмотров

select /*+ index(V_AMV_PLG_ORDER_HISTORY_200_MS.orders.T0 IDX_ORDER_VERSION_3) */ * 
from V_AMV_PLG_ORDER_HISTORY_200_MS 
where EXCHANGE_SK = 32 and PRODUCT_SK = 1000169 

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

Как вы можете видеть, я запрашивая от просмотра V_AMV_PLG_ORDER_HISTORY_200_MS, вы можете увидеть его SQL-запрос здесь:

V_AMV_PLG_ORDER_HISTORY_200_MS view SQL Query: 


SELECT AMV_PERF_PROFILES_FRONTEND.AMV_PLG_GET_SEGMENT(200, orders.ORDER_GLOBAL_DATE_TIME) AS ORDER_DATE_TIME, 
SUM(orders.BASE_VOLUME) AS VOLUME, 
SUM(orders.BASE_CURR_LIMIT_PRICE*orders.BASE_VOLUME)/SUM(orders.BASE_VOLUME) AS PRICE, 
orders.PRODUCT_SK AS PRODUCT_SK, 
orders.EXCHANGE_SK AS EXCHANGE_SK, 
orders.DIRECTION_CD AS DIRECTION_CD, 
orders.AGG_UNIT_CD AS AGG_UNIT_CD, 
orders.TRADER_KEY AS EXECUTING_REPRESENTATIVE_KEY, 
orders.ACCOUNT_KEY AS ACCOUNT_KEY, 
a.BUSINESS_UNIT_CD AS BUSINESS_UNIT_CD 
FROM AMV_PERF_PROFILES_FRONTEND.S_AMV_ORDER_VERSION_NEW orders 
INNER JOIN AMV_PERF_PROFILES_FRONTEND.S_AMV_ACCOUNT a 
ON a.ACCOUNT_KEY = orders.ACCOUNT_KEY 
WHERE BASE_VOLUME > 0 
GROUP BY AMV_PERF_PROFILES_FRONTEND.AMV_PLG_GET_SEGMENT(200, orders.ORDER_GLOBAL_DATE_TIME), 
    orders.PRODUCT_SK, 
    orders.EXCHANGE_SK, 
    orders.ACCOUNT_KEY, 
    a.BUSINESS_UNIT_CD, 
    orders.AGG_UNIT_CD, 
    orders.TRADER_KEY, 
    orders.DIRECTION_CD; 

Он получает данные, используя Синоним S_AMV_ORDER_VERSION_NEW, который направляет на другую схему, к вид называется V_AMV_ORDER_VERSION и отсылая к нему как заказы, его SQL-запрос здесь:

V_AMV_ORDER_VERSION view Sql query: 


    SELECT T1.ENTITY_KEY , 
    T2.AGG_UNIT_CD , 
    T0.BASE_CURR_LIMIT_PRICE , 
    T7.DIRECTION_CD , 
    T0.EXCHANGE_SK, 
    T0.ORDER_LOCAL_DATE_TIME , 
    T0.PRODUCT_SK, 
    T18.ENTITY_KEY , 
    T19.ENTITY_KEY , 
    T0.NOTIONAL_VALUE2 , 
    T0.NOTIONAL_VALUE , 
    T0.ORDER_GLOBAL_DATE_TIME , 
    T0.BASE_VOLUME , 
    T31.TRANSACTION_STATUS_CD , 
    T0.ORDER_VERSION_KEY 
    FROM ETS_UDM_CDS_NEW.ORDER_VERSION T0 
    LEFT OUTER JOIN ETS_UDM_CDS_NEW.ENTITY T1 
    ON T0.ACCOUNT_SK = T1.ENTITY_SK 
    LEFT OUTER JOIN ETS_UDM_CDS_NEW.AGG_UNIT T2 
    ON T0.AGG_UNIT_SK = T2.ENTITY_SK 
    LEFT OUTER JOIN ETS_UDM_CDS_NEW.DIRECTION T7 
    ON T0.DIRECTION_SK = T7.ENTITY_SK 
    LEFT OUTER JOIN ETS_UDM_CDS_NEW.ENTITY T18 
    ON T0.LOCAL_TIME_ZONE_SK = T18.ENTITY_SK 
    LEFT OUTER JOIN ETS_UDM_CDS_NEW.ENTITY T19 
    ON T0.TRADER_SK = T19.ENTITY_SK 
    LEFT OUTER JOIN ETS_UDM_CDS_NEW.TRANSACTION_STATUS T31 
    ON T0.TRANSACTION_STATUS_SK = T31.ENTITY_SK; 

Который берет данные из таблицы называется ORDER_VERSION и относится к нему как T0 эта таблица имеет индекс с именем IDX_ORDER_VERSION

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

Я бы сказал, что если я иду один шаг вперед и запрос непосредственно из V_AMV_ORDER_VERSION (без синонима) IT работает и я могу сделать оракул работать с любым индексом я хочу, так что этот запрос работает отлично:

select /*+ index(orders.T0 IDX_ORDER_VERSION_5) */ * from V_AMV_ORDER_VERSION orders 
where EXCHANGE_SK =32 and PRODUCT_SK = 1000169 
+0

Oracle документация говорит. если представление сложное, то подсказки не будут распространяться на базовые таблицы. –

ответ

2

Ну, я и наш администратор нашей компании некоторое время смотрели на него, это похоже на ошибку Oracle в проявлении Global Hint. Мы создали представление V_AMV_PLG_ORDER_HISTORY_200_MS, используя регулярное соединение г, чем ANSI присоединиться, и теперь он работает правильно:

V_AMV_PLG_ORDER_HISTORY_200_MS посмотреть SQL-запрос:

SELECT AMV_PERF_PROFILES_FRONTEND.AMV_PLG_GET_SEGMENT(200, orders.ORDER_GLOBAL_DATE_TIME) AS ORDER_DATE_TIME, 
SUM(orders.BASE_VOLUME) AS VOLUME, 
SUM(orders.BASE_CURR_LIMIT_PRICE*orders.BASE_VOLUME)/SUM(orders.BASE_VOLUME) AS PRICE, 
orders.PRODUCT_SK AS PRODUCT_SK, 
orders.EXCHANGE_SK AS EXCHANGE_SK, 
orders.DIRECTION_CD AS DIRECTION_CD, 
orders.AGG_UNIT_CD AS AGG_UNIT_CD, 
orders.TRADER_KEY AS EXECUTING_REPRESENTATIVE_KEY, 
orders.ACCOUNT_KEY AS ACCOUNT_KEY, 
a.BUSINESS_UNIT_CD AS BUSINESS_UNIT_CD 

FROM AMV_PERF_PROFILES_FRONTEND.S_AMV_ORDER_VERSION_NEW orders, 
AMV_PERF_PROFILES_FRONTEND.S_AMV_ACCOUNT a 
WHERE BASE_VOLUME > 0 AND a.ACCOUNT_KEY = orders.ACCOUNT_KEY 

GROUP BY AMV_PERF_PROFILES_FRONTEND.AMV_PLG_GET_SEGMENT(200, orders.ORDER_GLOBAL_DATE_TIME), 
orders.PRODUCT_SK, 
orders.EXCHANGE_SK, 
orders.ACCOUNT_KEY, 
a.BUSINESS_UNIT_CD, 
orders.AGG_UNIT_CD, 
orders.TRADER_KEY, 
orders.DIRECTION_CD; 

 Смежные вопросы

  • Нет связанных вопросов^_^