If you need a specific SQL, the best way to use it is with CreateSQLQuery.
There's a whole chapter dedicated to that:
http://nhforge.org/doc/nh/en/index.html#querysql

    Diego


On Mon, Nov 8, 2010 at 19:22, Michael Smith <[email protected]> wrote:

> I'm using the Criteria API to build up a highly variable query.  This is
> working great for returning the proper results based on the inputs, but in
> some circumstances, performance is abysmal.  Our DBA is recommending a
> specific query optimization that addresses these issues, but I am unable to
> determine how to translate this into NHibernate query code.
>
> The simplest query that demonstrates the problem is created using something
> like the following usage of the Criteria API:
>
> int inputX = ...;
> string inputY = ...;
>
> DetachedCriteria criteria = DetachedCriteria.For(typeof(MappedEntity));
>
> SqlString sql = new SqlString
>     ("{alias}.ID in (select ID FROM [dbo].[UserDefinedFunction](",
>     Parameter.Placeholder, "))");
> criteria.Add(Expression.Sql(sql, inputX, NHibernateUtil.Int32));
>
> SqlString sql = new SqlString
>     ("{alias}.ProjectId in (",
>      "SELECT [Key] FROM CONTAINSTABLE(dbo.MappedEntity,*,",
>      Parameter.Placeholder,
>      "))");
> criteria.Add(Expression.Sql(sql, inputY, NHibernateUtil.String));
>
>
>
> This translates to the following SQL:
>
> SELECT ...
>  FROM dbo.MappedEntity this_
> WHERE this_.ID in (
>     SELECT ID
>     FROM [dbo].[UserDefinedFunction](@p0)
> )
> and this_.ID in (
>     SELECT [Key]
>     FROM CONTAINSTABLE(dbo.MappedEntity,*,@p1)
> )
>
>
> That SQL is exactly equivalent to the following with regards to the
> generated query plan and performance:
>
> SELECT ...
>  FROM dbo.MappedEntity this_
> INNER JOIN [dbo].[UserDefinedFunction](@p0) udf ON udf.ID = this_.ID
> WHERE this_.ID in (
>     SELECT [Key]
>     FROM CONTAINSTABLE(dbo.MappedEntity,*,@p1)
> )
>
>
>
> The performance issue is addressed by adding a "merge" join hint:
>
> SELECT ...
> FROM dbo.MappedEntity this_
> INNER *MERGE *JOIN [dbo].[UserDefinedFunction](@p0) udf
>     ON udf.ID = this_.ID
> WHERE this_.ID in (
>     SELECT [Key]
>     FROM CONTAINSTABLE(dbo.MappedEntity,*,@p1)
> )
>
>
> First off, is there any way to map a parameterized user-defined function
> such that we could even join with it (rather than having it in the where
> clause like we do now)?
>
> Secondly, if there is such a way, is there some method of providing join
> hints in the underlying sql?
>
> Any alternative suggestions are also welcome.
>
> Regards,
> Michael
>
> P.S.  Note:  the performance issues seem to be caused by SQL Server's query
> analyzer assuming that the user defined function returns a single row (since
> it can't maintain statistics on the temporary return table to know
> otherwise) and thus uses a nested loop to combine it with the additional
> restrictions.  Since there are thousands of matches rather than one, a merge
> join is much better than the nested loop.  We're simultaneously looking at
> ways to re-write the table-valued function to avoid the situation to begin
> with, but the odds of that are very small).
>
> --
> You received this message because you are subscribed to the Google Groups
> "nhusers" group.
> To post to this group, send email to [email protected].
> To unsubscribe from this group, send email to
> [email protected]<nhusers%[email protected]>
> .
> For more options, visit this group at
> http://groups.google.com/group/nhusers?hl=en.
>

-- 
You received this message because you are subscribed to the Google Groups 
"nhusers" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/nhusers?hl=en.

Reply via email to