тип данных clob вызывает проблемы с производительностью - PullRequest
2 голосов
/ 01 апреля 2020

ОБНОВЛЕНО: код работает должным образом, но производительность очень низкая. Когда я выполняю поиск без включения данных CLOB, запрос выполняется очень быстро, но если я включаю переменную CLOB в свой поиск, запрос выполняется очень медленно. Я использую CLOB для передачи больших строковых данных ('aaaaaaa, bbbb, c, dd ddd ...') и сохраняю эти данные в глобальной таблице для повышения производительности, я думал, что это позволит максимально повысить производительность запросов. Как я могу улучшить / использовать мою переменную CLOB для лучшей производительности? Пожалуйста, посмотрите на код ниже для получения дополнительной информации. Ценим за любую помощь. Я все еще борюсь с производительностью, может кто-нибудь помочь / предоставить какие-либо предложения, пожалуйста.

GLOBAL TT GlobalTemp_EMP( //this already exists
emp_refno (30 byte);
)


Create or replace PROCEDURE Employee(

emp_refno IN CLOB

)

AS

Begin
OPEN p_resultset FOR
with inputs ( str ) as (  //red error line here 
       select to_clob(emp_refno )
       from dual
     ),
     prep ( s, n, token, st_pos, end_pos ) as (
       select ',' || str || ',', -1, null, null, 1
         from inputs
       union all
       select s, n+1, substr(s, st_pos, end_pos - st_pos),
              end_pos + 1, instr(s, ',', 1, n+3)
         from prep
         where end_pos != 0
     )
INSERT into GlobalTemp_EMP   //red error line here 
select token from prep;


select e.empname, e.empaddress, f.department
from employee e
join department f on e.emp_id = t.emp_id
and e.emp_refno  in (SELECT emp_refno from GlobalTemp_EMP) //using GTT In subquery

Ответы [ 3 ]

4 голосов
/ 02 апреля 2020

put this code between BEGIN and OPEN p_resultset FOR : this might have some performance issue though.
INSERT into GlobalTemp_EMP 
with inputs ( str ) as (  
       select to_clob(emp_refno )
       from dual
     ),
     prep ( s, n, token, st_pos, end_pos ) as (
       select ',' || str || ',', -1, null, null, 1
         from inputs
       union all
       select s, n+1, substr(s, st_pos, end_pos - st_pos),
              end_pos + 1, instr(s, ',', 1, n+3)
         from prep
         where end_pos != 0
     )
  
select token from prep where token is not NULL;
0 голосов
/ 06 апреля 2020

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

Для сравнения CLOBs вы должны использовать dbms_lob.compare. Я думаю, = сделает неявное преобразование в varchar (и усечет), затем проведет сравнение.

0 голосов
/ 06 апреля 2020

Ниже приведен неверный синтаксис:

GLOBAL TT GlobalTemp_EMP( //this already exists
emp_refno (30 byte);
)

Я не знаю причину использования байтовой семантики, или вы определили ее как clob, char или varchar2.

Если это в настоящее время сабл, тогда, возможно, вы могли бы определить столбец как emp_refno varchar2(30 char) и добавить уникальный индекс, изменив процедуру Employee для вставки только новых идентификаторов. Индекс поможет вставкам больше, чем когда вы его читаете.

Если вы хотите вставить огромное количество данных в GlobalTemp_EMP быстрее, я бы рекомендовал сделать его обычной таблицей, предварительно обрабатывая данные (например, в Perl или другом языке), чтобы разделить идентификаторы вне Oracle, а затем использовать SQL* Loader. Или, возможно, внешний стол.

...