2015-10-14 1 views
0

У нас есть таблица, в которой хранится информация о пользователе в парах имени и значении атрибута. В этой таблице мы создали представление путем переноса строк в столбцы с использованием декодирования. MAX(DECODE(attribute_name,'FirstName',attribute_Value)) FirstNameСоздание указателя на функции максимального декодирования

CREATE OR REPLACE FORCE VIEW vw_get_userinfo 
("USER_ID", "FIRSTNAME", "LASTNAME", "USEREMAIL", 
    "STREET", "CITY", "STATE", "ZIPCODE", "COUNTRY") 
AS 
    SELECT 
    t.user_id, 
    t.firstname, 
    t.lastname, 
    t.useremail, 
    t.street, 
    t.city, 
    t.state, 
    t.country 
    FROM (WITH 
      tempattributes AS (SELECT 
           user_id, 
           attribute_name, 
           attribute_value 
          FROM user_details) 
     SELECT 
      user_id, 
      MAX(DECODE(attribute_name, 'FirstName', attribute_value)) FirstName, 
      MAX(DECODE(attribute_name, 'LastName', attribute_value)) LastName, 
      MAX(DECODE(attribute_name, 'UserEmail', attribute_value)) UserEmail, 
      MAX(DECODE(attribute_name, 'Street', attribute_value)) Street, 
      MAX(DECODE(attribute_name, 'City', attribute_value))  City, 
      MAX(DECODE(attribute_name, 'State', attribute_value))  State, 
      MAX(DECODE(attribute_name, 'ZipCode', attribute_value)) Zipcode, 
      MAX(DECODE(attribute_name, 'Country', attribute_value)) Country 
     FROM tempattributes 
     GROUP BY user_id 
     ) t 

Во время объяснения плана, полное сканирование выполняется при запросе с первым полем имени. Функциональный индекс не применим в этом случае, поскольку индекс не будет работать в группе по функциям. Есть ли способ создать индекс в атрибуте FirstName?

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

+1

Если вам нужны рекомендации по эффективности, вы должны показать весь запрос. –

+0

Спасибо @ GordonLinoff. Я включил запрос. –

+0

Я не вижу предиката фильтра в запросе. Вы проецируете все строки из таблицы. Очевидно, требуется «полное сканирование таблицы». Когда вы фильтруете данные на основе «столбца», имеет смысл создать «индекс» в этом столбце. Если вы фильтруете данные на основе «выражения», тогда вам нужно создать «функциональный индекс» в этом столбце. Вам не нужен индекс для проецирования строк. Опубликуйте ** ПРОГРАММНЫЙ ПЛАН **. См. [Как создать и отобразить EXPLAIN PLAN] (http://lalitkumarb.com/2014/05/31/oracle-explain-plan/) –

ответ

0

«Есть ли способ создать индекс в атрибуте FirstName?»

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

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

Если вы не хотите определять фиксированный набор атрибутов, по какой-либо причине вы должны выбрать поддерживаемый подход, такой как XML, или JSON в 12c. По крайней мере, их атрибуты индексируются. Find out more.

0

Это не может помочь производительность, но вы можете просто написать запрос как:

SELECT user_id, 
     MAX(DECODE(attribute_name,'FirstName',attribute_Value)) as FirstName, 
     MAX(DECODE(attribute_name,'LastName',attribute_Value)) as LastName, 
     MAX(DECODE(attribute_name,'UserEmail',attribute_Value)) as UserEmail, 
     MAX(DECODE(attribute_name,'Street',attribute_Value)) as Street, 
     MAX(DECODE(attribute_name,'City',attribute_Value)) as City, 
     MAX(DECODE(attribute_name,'State',attribute_Value)) as State, 
     MAX(DECODE(attribute_name,'ZipCode',attribute_Value)) as ZipCode, 
     MAX(DECODE(attribute_name,'Country',attribute_Value)) as Country 
FROM user_details 
GROUP BY user_id; 

(Примечание:. Я предпочитаю CASE к DECODE(), но я уезжаю исходную логику)

У Oracle хороший оптимизатор, но возможно, что вложенные with повлияли на него, так что это может работать лучше. Вы также можете попробовать указатель на user_details(user_id, attribute_name, attribute_value), чтобы узнать, повышает ли это производительность.

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