我的表有大约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将不胜感激。 非常感谢。
答案 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毫秒