SQL خادم 2005 النص الكامل منتدى البحث
-
03-07-2019 - |
سؤال
وأنا أعمل على إجراء بحث تخزينها لالمنتديات الموجودة لدينا.
ولقد كتابة التعليمات البرمجية التالية والذي يستخدم SQL القياسية فهارس النص الكامل، ولكن أنا متأكد من أن هناك طريقة أفضل للقيام بذلك، ونود نقطة في الاتجاه الصحيح.
لإعطاء بعض المعلومات حول الطريقة التي يجب أن تعمل، والصفحة تحتوي على مربع النص 1 البحث التي عند النقر عليها سيتم البحث في عناوين المواضيع، والأوصاف موضوع ونص آخر ويجب أن تعود النتائج مع عنوان مباريات أولا، ثم الوصف ثم نشر البيانات .
وفيما يلي ما كتبته حتى الآن الذي يعمل ولكن ليس أنيقة أو بأسرع ما أود. وعلى سبيل المثال من الأداء مع 20K المواضيع والمشاركات 80K يستغرق حوالي 12 ثانية للبحث عن 5 كلمات عشوائية.
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
وأنا أعلم به قليلا ينضب طويلة ولكن مجرد دفعة في الاتجاه الصحيح موضع تقدير جيد.
أكان ذلك يساعد 80٪ من الوقت الاستعلام تناولها عندما المشاركات البحث وفقا للتيه خطة الاستعلام ينفق على "مجمع الفهرس التفحص" على المشاركات الجدول. أنا غير قادر على رؤية أي حال حول هذا الأمر.
والشكر
وغافن
المحلول
وكنت قد حقا أن نرى شرح خطة لتعرف أين كانت أجزاء بطيئة، وأنا لا أرى أي شيء خشن مع الخصم في التعليمات البرمجية. أول شيء جدا - تأكد من كل ما تبذلونه من المؤشرات هي في حالة جيدة، وتستخدم فيه، إحصاءات محدثة، الخ
واحد فكرة أخرى تتمثل في قيام البحث على عنوان الموضوع أولا، ثم استخدام النتائج من تلك لتقليم عمليات البحث على وصف موضوع ونص آخر. وبالمثل، استخدم النتائج من وصف موضوع البحث لتقليم بحث آخر النص.
والفكرة الأساسية هنا هي أنه إذا وجدت الكلمات الرئيسية في عنوان الموضوع، لماذا عناء البحث في الوصف والمشاركات؟ وأنا أدرك هذا قد لا تعمل اعتمادا على الطريقة التي يتم عرض نتائج البحث للمستخدم، وأنه قد لا تحدث فرقا كبيرا، ولكن هذا شيء للتفكير.
نصائح أخرى
والسجلات 80K ليست من ذلك بكثير. أود أن أوصى ليس إدخال البيانات الناتجة في جدول مؤقت الخاصة بك، وبدلا من ذلك فقط إدراج معرفات، ثم الانضمام إلى هذا الجدول بعد ذلك. وهذا سيوفر على كتابة إلى جدول مؤقت، كما يمكنك تخزين 10000 [إينتس]، بدلا من 10000 المشاركات كاملة (من الذي تجاهل جميع ولكن صفحة واحدة من). هذا قد يقلل من مقدار الوقت الذي يقضيه المشاركات المسح، كذلك.
ويبدو أنك ستحتاج جدولين درجة الحرارة، واحدة للمواضيع واحد للوظائف. لو كنت اتحاد لهم في اختيار النهائي.