【发布时间】:2011-10-07 15:21:41
【问题描述】:
背景
我有以下函数,它根据结果与搜索值的匹配程度对结果进行排名:
CREATE FUNCTION [dbo].[fnGetRelevance]
(
@fieldName nvarchar(50),
@searchTerm nvarchar(50)
)
RETURNS int
AS
BEGIN
if (@fieldName like @searchTerm + '%') -- starts with
begin
return 0
end
else if ((@fieldName like '%' + @searchTerm + '%') and (@fieldName not like @searchTerm + '%')) -- contains, but doesn't start with
begin
return 1
end
return 1
END
因此,在以下查询(NHibernate 查询)的上下文中,它基于搜索字符串 Allianz RCM BRIC Stars A 搜索共享类,它会找到 39 个结果并对它们进行排名,以便与该字符串完全匹配的结果位于顶部,其余的按字母顺序排列在它下面。
select top 50 *
from ShareManager.ShareClass sc
-- and a few other tables with an inner join and a left join
where (sc.ShareClass_Id in
(
/* filter by some business criteria which is a single
select statement that does 2 more inner joins */
)
and 1 = 1
and (sc.ShareClass_Name like '%Allianz%' /* @p11 */)
and (sc.ShareClass_Name like '%RCM%' /* @p12 */)
and (sc.ShareClass_Name like '%BRIC%' /* @p13 */)
and (sc.ShareClass_Name like '%Stars%' /* @p14 */)
and (sc.ShareClass_Name like '%A%' /* @p15 */)
order by dbo.fngetrelevance(sc.ShareClass_Name, 'Allianz RCM BRIC Stars A'), sc.ShareClass_Name asc
问题
我遇到的问题是 dbo.fngetrelevance 导致我的 NHibernate 查询超时。我尝试过延长超时时间,但这不起作用,而且我认为这不是真正的问题。当我删除该功能时,它按预期工作。
SQL Server 2008 上是否有一种方法可以加快这一速度,或者使用 NHibernate 以不会超时的方式实现排名?
补充信息
我希望有人会建议我减少连接数。为了尽可能加快这些查询的速度,我们已经进行了很多优化。在修改整体架构的规模上,弄清楚如何进一步优化对我们来说将是一项巨大的努力。不幸的是,在游戏的这个阶段,我们不会获得批准,(据我目前所见,只有 1 只基金)
作为记录,这就是我在 NHibernate 中使用该函数的方式:
string querystring =
"select sc, sctr" +
" from ShareClass as sc" +
// joins to 2 other tables
" and (" + expressionTokenizer.ToResult("sc.Name") + ") "
+ this.AddShareClassOrder(order, "sc", "sctr", searchExpression);
var result = _session.CreateQuery(querystring)
.AddNameSearchCriteria(expressionTokenizer)
.AddDataUniverseParameters(dataUniverseHelper)
.SetFirstResult((pageSize * (pageNum - 1)))
.SetMaxResults(pageSize)
.List();
AddShareClassOrder 有效返回
fieldName = string.Format("dbo.fngetrelevance({1}.{2}, '{0}'), {1}.{2}", textToSearchFor, shareClassPrefix, "Name");
return String.Format(" order by {0} {1}", fieldName, direction);
或者,SQL 中表示的以下内容:
dbo.fngetrelevance(sc.ShareClass_Name, 'Allianz RCM BRIC Stars A'), sc.ShareClass_Name asc
【问题讨论】:
标签: c# sql sql-server nhibernate query-optimization