简体   繁体   English

NHibernate和自定义SQL子查询(使用临时表)

[英]NHibernate and custom SQL subquery (using temp table)

Is it possible to use custom SQL for a sub query "IN" parameter. 是否可以对子查询“ IN”参数使用自定义SQL。 Currently, we successfully build the sub query (subQueryEstate) however it's a complicated chunk of SQL which can take time to process for larger datasets. 当前,我们已经成功构建了子查询(subQueryEstate),但这是一个复杂的SQL块,需要花费一些时间来处理较大的数据集。 The code generating a query using our existing sub query is as follows: 使用我们现有的子查询生成查询的代码如下:

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();

To improve the speed of execution we have an idea to use a temp table (transactional life-cycle) that we will populate with ID's. 为了提高执行速度,我们有一个想法,就是使用一个临时表(事务生命周期),该表将填充ID。 The idea is to then either join to the temp table or use a much simpler sub query (SELECT ID FROM TEMP_TABLE) instead of the more complicated original. 这个想法是然后要么连接到临时表,要么使用更简单的子查询(SELECT ID FROM TEMP_TABLE)代替更复杂的原始查询。

Can we use a table that isn't mapped as a sub query in NHibernate? 我们可以使用未在NHibernate中映射为子查询的表吗? Can we write custom SQL or create a detached criteria to pass as parameter to the IN clause? 我们是否可以编写自定义SQL或创建分离的条件以作为参数传递给IN子句? We would like to preserve the fact NHibernate is producing the correct SQL for the remainder of the query. 我们想保留一个事实,即NHibernate正在为其余查询生成正确的SQL。

Ideally something like: 理想情况是:

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();

Thoughts? 思考? Ideas? 想法? There might be a more elegant solution we haven't thought about. 可能有一个我们尚未考虑过的更优雅的解决方案。

In the end we used temporary tables to solve the problem. 最后,我们使用临时表解决了该问题。 As our app uses a firebird database we created four global temporary tables having a "transaction" life-cylce. 当我们的应用程序使用firebird数据库时,我们创建了四个具有“事务”生命周期的全局临时表。 That is, the data in a temp table is only valid for the life of the transaction. 也就是说,临时表中的数据仅在事务有效期内有效。

The SQL used to create the temp table (note we created four to satisfy our use case) 用于创建临时表的SQL(请注意,为了满足用例,我们创建了四个)

create global temporary table TEMP_TABLE_ID1 (ID BIGINT NOT NULL) on commit delete rows; 在提交删除行上创建全局临时表TEMP_TABLE_ID1(ID BIGINT NOT NULL); CREATE INDEX IDX_TEMP_TABLE_ID1 ON TEMP_TABLE_ID1(ID); CREATE INDEX IDX_TEMP_TABLE_ID1 ON TEMP_TABLE_ID1(ID);

Using temp tables we can now systematically populate them with ID's from a master query. 现在,使用临时表,我们可以使用主查询中的ID系统地填充它们。 Filter subsequent queries by either using a sub-query or join to the temp table which is a much faster approach than using a large sub-query for each "downstream" query. 通过使用子查询或联接到临时表来过滤后续查询,这比对每个“下游”查询使用大型子查询要快得多。 Performance is dramatically improved using temp tables and because the tables are only valid for the life of the transaction it means we don't have to worry about cross-transaction pollution and/or purging the tables of data. 使用临时表可以显着提高性能,并且由于临时表仅在事务生命期内有效,这意味着我们不必担心交叉交易污染和/或清除数据表。

A very tidy solution. 一个非常整洁的解决方案。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM