FreeText العد الاستعلام عن جداول متعددة بطيئة عظمى
-
10-07-2019 - |
سؤال
لدي جدولين:
**Product**
ID
Name
SKU
**Brand**
ID
Name
الجدول المنتج لديها حوالي 120K السجلات العلامة التجارية الجدول 30K السجلات
كنت بحاجة إلى العثور على عدد جميع المنتجات مع اسم العلامة التجارية مطابقة الكلمات الرئيسية المحددة.
يمكنني استخدام freetext 'يحتوي على مثل هذا:
SELECT count(*)
FROM Product
inner join Brand
on Product.BrandID = Brand.ID
WHERE (contains(Product.Name, 'pants')
or
contains(Brand.Name, 'pants'))
هذا الاستعلام يأخذ عن 17 ثانية. وإعادة بناء FreeText مؤشر قبل تشغيل هذا الاستعلام.
إذا أنا فقط التحقق من المنتج.الاسم.أنها الاستعلام هو أقل من 1 ثانية.نفسه, إذا أنا فقط التحقق من العلامة التجارية.الاسم.تحدث هذه المشكلة إذا كنت تستخدم أو شرط.
إذا كنت تستخدم استعلام إلى استخدام مثل:
SELECT count(*)
FROM Product
inner join Brand
on Product.BrandID = Brand.ID
WHERE Product.Name LIKE '%pants%'
or
Brand.Name LIKE '%pants%'
فإنه يأخذ 1 ثانية.
قرأت على MSDN أن: http://msdn.microsoft.com/en-us/library/ms187787.aspx
البحث عن جداول متعددة ، واستخدام انضم إلى الجدول الخاص بك من بند إلى البحث على مجموعة نتائج هذا المنتج من جدولين أو أكثر.
لذلك أضفت داخلية انضم الجدول من:
SELECT count(*)
FROM (select Product.Name ProductName, Product.SKU ProductSKU, Brand.Name as BrandName FROM Product
inner join Brand
on product.BrandID = Brand.ID) as TempTable
WHERE
contains(TempTable.ProductName, 'pants')
or
contains(TempTable.BrandName, 'pants')
ينتج عن هذا الخطأ:لا يمكن استخدام يحتوي على أو FREETEXT المسند على العمود 'المنتج' لأنه ليس النص الكامل فهرستها.
لذا فإن السؤال هو لماذا أو حالة يمكن أن تسبب مثل بطء query ؟
المحلول
بعد قليل من المحاكمة خطأ لقد وجدت الحل الذي يبدو للعمل.فإنه ينطوي على خلق عرض مفهرسة:
CREATE VIEW [dbo].[vw_ProductBrand]
WITH SCHEMABINDING
AS
SELECT dbo.Product.ID, dbo.Product.Name, dbo.Product.SKU, dbo.Brand.Name AS BrandName
FROM dbo.Product INNER JOIN
dbo.Brand ON dbo.Product.BrandID = dbo.Brand.ID
GO
CREATE UNIQUE CLUSTERED INDEX IX_VW_PRODUCTBRAND_ID
ON vw_ProductBrand (ID);
GO
إذا قمت بتشغيل الاستعلام التالي:
DBCC DROPCLEANBUFFERS
DBCC FREEPROCCACHE
GO
SELECT count(*)
FROM Product
inner join vw_ProductBrand
on Product.BrandID = vw_ProductBrand.ID
WHERE (contains(vw_ProductBrand.Name, 'pants')
or
contains( vw_ProductBrand.BrandName, 'pants'))
يستغرق الآن 1 ثانية مرة أخرى.
نصائح أخرى
هل حاولت شيئا مثل:
SELECT count(*)
FROM Product
INNER JOIN Brand ON Product.BrandID = Brand.ID
WHERE CONTAINS((Product.Name, Brand.Name), 'pants')
أنا واجهت مشكلة مشابهة ولكن أنا ثابت مع الاتحاد ، شيء من هذا القبيل:
SELECT *
FROM Product
inner join Brand
on Product.BrandID = Brand.ID
WHERE contains(Product.Name, 'pants')
UNION
SELECT *
FROM Product
inner join Brand
on Product.BrandID = Brand.ID
WHERE contains(Brand.Name, 'pants'))