在大型表上进行简单有序查询时出现奇怪的全文搜索性能问题

时间:2011-03-05 16:55:59

标签: performance sql-server-2008 full-text-search sql-order-by large-data-volumes

我的表有大约7M条记录,其结构如下:

create table Locations (LocationID (PK, int, not null),LocationName varchar(100) NOT NULL  /*e.g. 'Paris'*/, ItemsNo (int, null), ICode char(1) null /*e.g. 'C'*/, LocationExtended nvarchar(max) null)

HTML版本: “create table Locations(LocationID(PK,int,not null),LocationName varchar(100)NOT NULL,ItemsNo(int,null),ICode char(1)null,LocationExtended nvarchar(max)null)”

我的查询非常简单:

select top 20 LocationName, ItemsNo from Locations where contains(LocationExtended,@SearchTerms) and Icode='C' and ItemsNo is not null order by ItemsNO desc

此处的HTML版本:“从包含(LocationExtended,@ SearchTerms)和Icode ='C'的位置选择前20名LocationName,ItemsNo,并且ItemsNo不是由ItemsNO desc订购的

当然,LocationExtended字段有一个全文目录。

现在让我们使用参数@SearchTerms以及索引:

如果我在LocationID列上只有一个聚簇索引,我会获得@ SearchTerms ='Paris and France'的快速执行时间(因为LocationExtended字段中包含巴黎和法国关键字的记录很少)和SLOW执行@ SearchTerms ='France'的时间(因为在LocationExtended字段中有数千条记录,对于法国的每个城市/城镇而言)。

换句话说,结果如下: for @ SearchTerms ='巴黎和法国'回归:“巴黎”和“巴黎北部”和“南巴黎” for @ SearchTerms ='France'返回“Paris”,“Nice”,“Marseille”,....等等......

因为我需要两种方案都能快速运行,所以我在Locations表上创建了一个非聚集索引,其中包含Icode和ItemsNO列以及包含LocationID的列。

通过制作这个新索引,我得到了相反的结果:@ SearchTerms ='France'的超快执行时间,但@ SearchTerms ='巴黎和法国'的速度很慢

现在我陷入困境。

我提到我在Windows 2003 Server上运行SQL Server 2008

任何ideea将不胜感激。 非常感谢。

2 个答案:

答案 0 :(得分:1)

OPTION (RECOMPILE)添加到SELECT查询,以允许优化程序“查看”@SearchTerms变量中的值,并相应地选择更好的计划。另外,请考虑重写查询以使用CONTAINSTABLE - 它通常更灵活。

答案 1 :(得分:0)

最后这对我有用:

索引:LocationID上的聚簇索引和ItemsNO上的非聚集索引,其中LocationID为包含的列

查询: select TOP 20 * from ( select ROW_NUMBER() over (order by ItemsNO DESC) as RowID,ItemsNO,LocationName FROM Locations where contains(LocationExtended,@SearchTerms) and ItemsNO>0 and ICode='C') t

这将执行时间从850毫秒减少到~45毫秒