Мое обходное решение:
create or replace type split_tbl as table of varchar(32767);
/
create or replace function split
(
p_list varchar2,
p_del varchar2 := ','
) return split_tbl pipelined
is
l_idx pls_integer;
l_list varchar2(32767) := p_list;
l_value varchar2(32767);
begin
loop
l_idx := instr(l_list,p_del);
if l_idx > 0 then
pipe row(substr(l_list,1,l_idx-1));
l_list := substr(l_list,l_idx+length(p_del));
else
pipe row(l_list);
exit;
end if;
end loop;
return;
end split;
/
Теперь вы можете использовать одну переменную для получения некоторых значений в таблице:
select * from table(split('one,two,three'))
one
two
three
select * from TABLE1 where COL1 in (select * from table(split('value1,value2')))
value1 AAA
value2 BBB
Итак, подготовленный оператор может быть:
"select * from TABLE where COL in (select * from table(split(?)))"
С уважением,
Хавьер Ибанез
означает, что LongAdder агрегирует значения внутри и обновляет их позже?
blockquote>Да, если я правильно понимаю ваше утверждение.
Каждый
Cell
вLongAdder
является вариантомAtomicLong
. Наличие нескольких таких ячеек является способом распространения конкуренции и, следовательно, увеличения пропускной способности.Когда конечный результат (сумма) должен быть восстановлен, он просто добавляет вместе значения каждой ячейки.
Большая часть логики вокруг того, как организованы ячейки, как они выделены и т. д., можно увидеть в источнике: http://hg.openjdk.java.net/jdk9/jdk9/jdk/file/f398670f3da7 /src/java.base/share/classes/java/util/concurrent/atomic/Striped64.java
В частности, количество ячеек связано числом процессоров:
/** Number of CPUS, to place bound on table size */ static final int NCPU = Runtime.getRuntime().availableProcessors();
Основная причина, по которой он «быстрее», - это заявленная производительность . Это важно, потому что:
При низком конфликте обновлений оба класса имеют схожие характеристики.
blockquote>Вы использовали LongAdder для очень частых обновлений, в который атомный CAS и собственные вызовы
Unsafe
будут вызывать конкуренцию . (См. источник и volatile читает ). Не говоря уже о промахах кеша / ложном совместном использовании на нескольких AtomicLongs (хотя я еще не смотрел макет класса, кажется, что до заполнения фактического поляlong
не было достаточного количества памяти.при высокой конкуренции ожидаемая пропускная способность этого класса значительно выше, за счет более высокого потребления пространства.
blockquote>Реализация расширяет
Striped64
, что является держатель данных для 64-битных значений. Значения хранятся в ячейках, которые дополняются (или чередуются), отсюда и имя. Каждая операция может на LongAdder изменять набор значений, присутствующих в Striped64. ячейка создается и изменяется, поэтому старый поток может заканчиваться одновременно с конкурирующим. Когда вам нужно конечное значение, суммы каждой ячейки просто складываются.К сожалению, производительность связана со стоимостью, который в этом случае является памятью (как это часто бывает). Striped64 может расти очень большой, если большая нагрузка потоков равна d).
Источник цитаты: Javadoc для LongAdder