假设我具有以下表结构:
create table PEOPLE (
ID integer not null primary key,
NAME varchar(100) not null
);
create table CHILDREN (
ID integer not null primary key,
PARENT_ID_1 integer not null references PERSON (id),
PARENT_ID_2 integer not null references PERSON (id)
);
,我想生成一个父母双方的姓名列表。光滑的我可以这样写:
for {
parent <- people
child <- children if {
parent.id === child.parent_id_1 ||
parent.id === child.parent_id_2
}
} yield {
parent.name
}
并生成预期的SQL:
select p.name
from people p, children c
where p.id = c.parent_id_1 or p.id = c.parent_id_2
但是,这并不是最佳选择:表达式的OR
部分可能会导致某些DBMS的性能异常降低,即使有索引,最终也会进行全表扫描以加入p.id
在那里(例如,参见this bug report for H2)。普遍的问题是查询计划者无法知道单独执行OR
的每一面并将结果重新结合在一起还是执行全表扫描[2]更快。
我想生成看起来像这样的SQL,然后可以按预期使用(主键)索引:
select p.name
from people p, children c
where p.id in (c.parent_id_1, c.parent_id_2)
我的问题是:如何才能做到这一点?现有方法似乎没有提供一种方法:
ColumnExtensionMethods.in
以Query
作为参数,但是我没有Query
我有一个数字或Rep[Long]
每个ID列< / p>
ColumnExtensionMethods.inSet
用于绑定现有(已知)文字数组,而不用于连接到列集
我想写的是这样的:
for {
parent <- people
child <- children
if parent.id in (child.parent_id_1, child.parent_id_2)
} yield {
p.name
}
但是现在不可能。
[1]我的实际设计要比这复杂一些,但是归结为相同的问题。
[2]一些DBMS do 具有针对某些简单情况的优化,例如OR-expansion in Oracle。