關於如何提高查詢性能的任何想法?緩慢的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