还有另一种选择:with
语法。要使用OP的示例,应如下所示:
with data as (
select 'value1' name from dual
union all
select 'value2' name from dual
union all
...
select 'value10000+' name from dual)
select field1, field2, field3
from table1 t1
inner join data on t1.name = data.name;
我遇到了这个问题。就我而言,我有一个Java数据列表,其中每个项目都有一个item_id和一个customer_id。我在数据库中有两个表,分别订阅了各个客户。我想获得该项目或该项目的客户的所有订阅的列表,以及该项目的ID。
我尝试了三种变体:
- Java中的多项选择(使用元组来绕过限制)
- 带语法
- 临时表
选项1:从Java中进行多项选择
基本上我先
select item_id, token
from item_subs
where (item_id, 0) in ((:item_id_0, 0)...(:item_id_n, 0))
然后
select cus_id, token
from cus_subs
where (cus_id, 0) in ((:cus_id_0, 0)...(:cus_id_n, 0))
然后,我以cus_id为键,并以商品列表作为值,用Java构建了一个Map,然后为每个找到的客户订阅添加(到第一个选择返回的列表中)具有该item_id的所有相关商品的条目。这是更混乱的代码
选项2:含语法
使用SQL一次获得所有内容
with data as (
select :item_id_0 item_id, :cus_id_0 cus_id
union all
...
select :item_id_n item_id, :cus_id_n cus_id )
select I.item_id item_id, I.token token
from item_subs I
inner join data D on I.item_id = D.item_id
union all
select D.item_id item_id, C.token token
from cus_subs C
inner join data D on C.cus_id = D.cus_id
选项3:临时表
创建一个具有三个字段的全局临时表:rownr(主键),item_id和cus_id。在其中插入所有数据,然后执行与选项2非常相似的选择,但是链接到临时表而不是with data
性能
这不是完全科学的性能分析。
- 我正在针对一个开发数据库运行,我的数据集中有略多于1000的行要查找其订阅。
- 我只尝试了一个数据集。
- 我与数据库服务器不在同一物理位置。距离不是很远,但是我确实注意到,如果我在家中通过VPN尝试,即使距离相同(尽管不是我的家庭互联网),但速度都慢得多。
- 我正在测试完整调用,所以我的API调用了另一个(也在dev的同一实例中运行),该API也连接到数据库以获取初始数据集。但这三种情况都是一样的。
YMMV。
也就是说,临时表选项要慢得多。如双倍慢。选项1获得14-15秒,选项2获得15-16,选项3获得30。
我将在与数据库服务器相同的网络上再次尝试它们,并在有机会时检查是否会改变情况。