关于如何提高查询性能的任何想法?缓慢的TSQL查询
[ftsIndex] PK是sID,wordPos。
并且在wordID,sID,wordPos上有一个索引。
它们都是int。
最后使用一个独特的。
大多数sID只有几个匹配。
某些sID可能有10,000个以上的匹配并且终止查询。
查询第一个27,749行在11秒内返回的位置。
没有一个sID有超过500个匹配。
个人比赛的总和是65,615。
27,750行本身需要2分钟以上,并有15,000场比赛。
因为最后加入的是[sID],这并不令人意外。
由于最终使用的不同,有没有办法把它找第一 肯定
on [wXright].[sID] = [wXleft].[sID]
and [wXright].[wordPos] > [wXleft].[wordPos]
and [wXright].[wordPos] <= [wXleft].[wordPos] + 10
然后移动到下一个SID?
我知道这是从查询优化器问很多,但这真的很酷。
在现实生活中,问题文档是零件清单和供应商重复多次。
select distinct [wXleft].[sID]
FROM
(-- begin [wXleft]
(-- start term
select [ftsIndex].[sID], [ftsIndex].[wordPos]
from [ftsIndex] with (nolock)
where [ftsIndex].[wordID] in
(select [id] from [FTSwordDef] with (nolock)
where [word] like 'Brown')
) -- end term
) [wXleft]
join
(-- begin [wRight]
(-- start term
select [ftsIndex].[sID], [ftsIndex].[wordPos]
from [ftsIndex] with (nolock)
where [ftsIndex].[wordID] in
(select [id] from [FTSwordDef] with (nolock)
where [word] like 'Fox')
) -- end term
) [wXright]
on [wXright].[sID] = [wXleft].[sID]
and [wXright].[wordPos] > [wXleft].[wordPos]
and [wXright].[wordPos] <= [wXleft].[wordPos] + 10
这使得它归结为1:40
inner loop join
我这样做只是尝试,它完全改变了查询计划。
我不知道问题查询需要多长时间。我在20点放弃了。
我甚至不会将此作为答案张贴,因为我没有看到它对任何人都有价值。
希望得到更好的答案。
如果在接下来的两天内我没有收到,我会删除这个问题。
这不能解决问题
select distinct [ft1].[sID]
from [ftsIndex] as [ft1] with (nolock)
join [ftsIndex] as [ft2] with (nolock)
on [ft2].[sID] = [ft1].[sID]
and [ft1].[wordID] in (select [id] from [FTSwordDef] with (nolock) where [word] like 'brown')
and [ft2].[wordID] in (select [id] from [FTSwordDef] with (nolock) where [word] like 'fox')
and [ft2].[wordPos] > [ft1].[wordPos]
and [ft2].[wordPos] <= [ft1].[wordPos] + 10
也支持类似“快速的棕色”查询与“狐狸”或“土狼”用别名,以便加入的10个字是不是一个很好的路径。
这需要14分钟(但至少它运行)。
这种格式再次不利于更高级的查询。
IF OBJECT_ID(N'tempdb..#tempMatch1', N'U') IS NOT NULL DROP TABLE #tempMatch1
CREATE TABLE #tempMatch1(
[sID] [int] NOT NULL,
[wordPos] [int] NOT NULL,
CONSTRAINT [PK1] PRIMARY KEY CLUSTERED
(
[sID] ASC,
[wordPos] ASC
))
IF OBJECT_ID(N'tempdb..#tempMatch2', N'U') IS NOT NULL DROP TABLE #tempMatch2
CREATE TABLE #tempMatch2(
[sID] [int] NOT NULL,
[wordPos] [int] NOT NULL,
CONSTRAINT [PK2] PRIMARY KEY CLUSTERED
(
[sID] ASC,
[wordPos] ASC
))
insert into #tempMatch1
select [ftsIndex].[sID], [ftsIndex].[wordPos]
from [ftsIndex] with (nolock)
where [ftsIndex].[wordID] in
(select [id] from [FTSwordDef] with (nolock)
where [word] like 'Brown')
--and [wordPos] < 100000;
order by [ftsIndex].[sID], [ftsIndex].[wordPos]
insert into #tempMatch2
select [ftsIndex].[sID], [ftsIndex].[wordPos]
from [ftsIndex] with (nolock)
where [ftsIndex].[wordID] in
(select [id] from [FTSwordDef] with (nolock)
where [word] like 'Fox')
--and [wordPos] < 100000;
order by [ftsIndex].[sID], [ftsIndex].[wordPos]
select count(distinct(#tempMatch1.[sID]))
from #tempMatch1
join #tempMatch2
on #tempMatch2.[sID] = #tempMatch1.[sID]
and #tempMatch2.[wordPos] > #tempMatch1.[wordPos]
and #tempMatch2.[wordPos] <= #tempMatch1.[wordPos] + 10
稍微不同的连接在5秒内运行(并且具有不同的查询计划)。
但我无法修复它的提示,因为它移动的地方它加入。
即使+1有超过10个文件,有超过7000比赛。
on [wXright].[sID] = [wXleft].[sID]
and [wXright].[wordPos] = [wXleft].[wordPos] + 1
全表DEF
CREATE TABLE [dbo].[FTSindex](
[sID] [int] NOT NULL,
[wordPos] [int] NOT NULL,
[wordID] [int] NOT NULL,
[charPos] [int] NOT NULL,
CONSTRAINT [PK_FTSindex] PRIMARY KEY CLUSTERED
(
[sID] ASC,
[wordPos] ASC
)WITH (PAD_INDEX = ON, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 100) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[FTSindex] WITH CHECK ADD CONSTRAINT [FK_FTSindex_FTSwordDef] FOREIGN KEY([wordID])
REFERENCES [dbo].[FTSwordDef] ([ID])
GO
ALTER TABLE [dbo].[FTSindex] CHECK CONSTRAINT [FK_FTSindex_FTSwordDef]
GO
我不知道你的所有数据,但你有没有想过可能插入临时表,然后创建聚簇索引呢?先插入,然后创建索引。这通常比创建索引本身更快。这可能对你有所帮助,可能不会,所以我想把它作为评论添加。 – djangojazz
@djangojazz插入只需要5秒钟。如果我添加一个排序,所以记录按PK顺序插入,它仍然是5秒。 – Paparazzi
我们将需要表/键/索引定义和查询计划(实际)。此外,这种设计/方法是否有任何理由,与仅使用SQL Server全文搜索相反? – RBarryYoung