Я работаю над поисковой хранимой процедурой для существующих форумов.SQL Server 2005 Full Text forum Поиск
Я написал следующий код, который использует стандартные текстовые индексы SQL, но я уверен, что есть лучший способ сделать это и хотел бы, чтобы точка была в правильном направлении.
Чтобы предоставить информацию о том, как она должна работать, на странице есть 1 текстовое окно поиска, которое при нажатии будет искать заголовки потоков, описания потоков и текст сообщения и должно возвращать результаты с совпадением заголовков вначале, затем описания затем публикуются данные.
Ниже я пишу до сих пор, что работает, но не изящно и не так быстро, как хотелось бы. Чтобы привести пример производительности с потоками 20К и сообщениями на 80 000, для поиска 5 случайных слов требуется около 12 секунд.
ALTER PROCEDURE [dbo].[SearchForums]
(
--Input Params
@SearchText VARCHAR(200),
@GroupId INT = -1,
@ClientId INT,
--Paging Params
@CurrentPage INT,
@PageSize INT,
@OutTotalRecCount INT OUTPUT
)
AS
--Create Temp Table to Store Query Data
CREATE TABLE #SearchResults
(
Relevance INT IDENTITY,
ThreadID INT,
PostID INT,
[Description] VARCHAR(2000),
Author BIGINT
)
--Create and populate table of all GroupID's This search will return from
CREATE TABLE #GroupsToSearch
(
GroupId INT
)
IF @GroupId = -1
BEGIN
INSERT INTO #GroupsToSearch
SELECT GroupID FROM SNetwork_Groups WHERE ClientId = @ClientId
END
ELSE
BEGIN
INSERT INTO #GroupsToSearch
VALUES(@GroupId)
END
--Get Thread Titles
INSERT INTO #SearchResults
SELECT
SNetwork_Threads.[ThreadId],
(SELECT NULL) AS PostId,
SNetwork_Threads.[Description],
SNetwork_Threads.[OwnerUserId]
FROM
SNetwork_Threads
INNER JOIN SNetwork_Groups ON SNetwork_Groups.GroupId = SNetwork_Threads.GroupId
WHERE
FREETEXT(SNetwork_Threads.[Description], @SearchText) AND
Snetwork_Threads.GroupID IN (SELECT GroupID FROM #GroupsToSearch) AND
SNetwork_Groups.ClientId = @ClientId
--Get Thread Descriptions
INSERT INTO #SearchResults
SELECT
SNetwork_Threads.[ThreadId],
(SELECT NULL) AS PostId,
SNetwork_Threads.[Description],
SNetwork_Threads.[OwnerUserId]
FROM
SNetwork_Threads
INNER JOIN SNetwork_Groups ON SNetwork_Groups.GroupId = SNetwork_Threads.GroupId
WHERE
FREETEXT(SNetwork_Threads.[Name], @SearchText) AND
Snetwork_Threads.GroupID IN (SELECT GroupID FROM #GroupsToSearch) AND
SNetwork_Groups.ClientId = @ClientId
--Get Posts
INSERT INTO #SearchResults
SELECT
SNetwork_Threads.ThreadId,
SNetwork_Posts.PostId,
SNetwork_Posts.PostText,
SNetwork_Posts.[OwnerUserId]
FROM
SNetwork_Posts
INNER JOIN SNetwork_Threads ON SNetwork_Threads.ThreadId = SNetwork_Posts.ThreadId
INNER JOIN SNetwork_Groups ON SNetwork_Groups.GroupId = SNetwork_Threads.GroupId
WHERE
FREETEXT(SNetwork_Posts.PostText, @SearchText) AND
Snetwork_Threads.GroupID IN (SELECT GroupID FROM #GroupsToSearch) AND
SNetwork_Groups.ClientId = @ClientId
--Return Paged Result Sets
SELECT @OutTotalRecCount = COUNT(*) FROM #SearchResults
SELECT
#SearchResults.[ThreadID],
#SearchResults.[PostID],
#SearchResults.[Description],
#SearchResults.[Author]
FROM
#SearchResults
WHERE
#SearchResults.[Relevance] >= (@CurrentPage - 1) * @PageSize + 1 AND
#SearchResults.[Relevance] <= @CurrentPage*@PageSize
ORDER BY Relevance ASC
--Clean Up
DROP TABLE #SearchResults
DROP TABLE #GroupsToSearch
Я знаю, что он немного длинный, но просто подталкивание в правильном направлении было бы хорошо оценено.
Incase it help 80% времени запроса занято, когда поисковые сообщения и согласно плану запроса расходуются на «Clustered Index Scan» в таблице сообщений. В любом случае, я не вижу этого.
Благодаря
Gavin
Я отредактировал мое сообщение, спасибо за совет, обязательно посмотрит на результаты описания потока. Если он помогает, 80% времени запроса тратится на поисковые сообщения и тратится на «Clustered Index Scan» в таблице сообщений. Я не думаю, что могу избежать этого на столе из 80 тыс. Записей? – Gavin
Нет, вероятно, мало того, что вы можете сделать, чтобы этого избежать. Возможно, вам захочется взглянуть на IOs на это - у вас достаточно памяти на вашем сервере для загрузки этого индекса, или это будут пейджинговые части в и из памяти? –