2

是否可以将自定义 SQL 用于子查询“IN”参数。目前,我们成功构建了子查询 (subQueryEstate),但它是一个复杂的 SQL 块,可能需要时间来处理更大的数据集。使用我们现有的子查询生成查询的代码如下:

session.QueryOver(() => cAlias)
.WithSubquery.WhereProperty(x => x.CPE.ID).In(subQueryEstate)
.JoinAlias(x => x.Costs, () => aCosts, JoinType.LeftOuterJoin)
.JoinAlias(x => x.Open, () => aOpen, JoinType.InnerJoin)
.List();

为了提高执行速度,我们有一个想法是使用一个临时表(事务生命周期),我们将用 ID 填充该表。这个想法是要么加入临时表,要么使用更简单的子查询(SELECT ID FROM TEMP_TABLE)而不是更复杂的原始查询。

我们可以在 NHibernate 中使用未映射为子查询的表吗?我们可以编写自定义 SQL 或创建一个分离的条件作为参数传递给 IN 子句吗?我们希望保留 NHibernate 为查询的其余部分生成正确 SQL 的事实。

理想情况下是这样的:

session.QueryOver(() => cAlias)
.WithSubquery.WhereProperty(x => x.CPE.ID).In("SELECT ID FROM TEMP_TABLE")
.JoinAlias(x => x.Costs, () => aCosts, JoinType.LeftOuterJoin)
.JoinAlias(x => x.Open, () => aOpen, JoinType.InnerJoin)
.List();

想法?想法?可能有一个我们没有想到的更优雅的解决方案。

4

1 回答 1

1

最后我们使用临时表来解决这个问题。由于我们的应用程序使用 firebird 数据库,我们创建了四个具有“事务”生命周期的全局临时表。也就是说,临时表中的数据仅在事务的生命周期内有效。

用于创建临时表的 SQL(注意我们创建了四个以满足我们的用例)

在提交删除行上创建全局临时表 TEMP_TABLE_ID1 (ID BIGINT NOT NULL);在 TEMP_TABLE_ID1(ID) 上创建索引 IDX_TEMP_TABLE_ID1;

使用临时表,我们现在可以使用来自主查询的 ID 系统地填充它们。通过使用子查询或连接到临时表来过滤后续查询,这比对每个“下游”查询使用大型子查询要快得多。使用临时表可以显着提高性能,因为这些表仅在事务的生命周期内有效,这意味着我们不必担心交叉事务污染和/或清除数据表。

一个非常整洁的解决方案。

全局临时表 (Firebird) http://www.firebirdsql.org/refdocs/langrefupd21-ddl-table.html

于 2013-04-16T02:03:46.427 回答