有关如何提高此查询性能的任何想法?
[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] 上。
因为最终使用 distinct 有没有办法寻找第一个肯定
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:00 放弃了。
我什至不打算将此作为答案发布,因为我认为它对其他人没有价值。
希望有更好的答案。
如果我在接下来的两天内没有收到,我将删除该问题。
这不能解决它
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 个单词“fox”或“coyote”的“quick brown”等查询,因此使用别名连接不是一个好方法。
这需要 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 个文档,其中包含超过 7,000 个匹配项。
on [wXright].[sID] = [wXleft].[sID]
and [wXright].[wordPos] = [wXleft].[wordPos] + 1
全表定义
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