여러 테이블의 freetext count 쿼리는 매우 느립니다
-
10-07-2019 - |
문제
두 개의 테이블이 있습니다.
**Product**
ID
Name
SKU
**Brand**
ID
Name
제품 테이블에는 약 120k 레코드가 있습니다. 브랜드 테이블에는 30k 레코드가 있습니다.
특정 키워드와 일치하는 이름과 브랜드가있는 모든 제품을 찾아야합니다.
나는 다음과 같은 freetext 'contains'를 사용합니다.
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
여러 테이블을 검색하려면 From Clause의 결합 된 테이블을 사용하여 두 개 이상의 테이블의 제품인 결과 세트를 검색하십시오.
그래서 내부 결합 테이블을 추가했습니다.
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')
이로 인해 오류가 발생합니다. 'ProductName'열에 포함 또는 freetext 술어를 사용할 수 없습니다.
따라서 문제는 - 왜 또는 상태가 느린 쿼리와 같은 일을 유발할 수 있습니까?
해결책
약간의 시험 후에 오류가 발생한 것처럼 보이는 솔루션을 찾았습니다. 인덱스 뷰를 만드는 것이 포함됩니다.
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')
나는 비슷한 문제에 부딪 쳤지 만 Union과 같은 문제를 해결했습니다.
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'))