質問

2つのテーブルがあります:

**Product**
ID
Name
SKU

**Brand**
ID
Name

製品テーブルには約120Kのレコードがあります ブランドテーブルには3万件のレコードがあります

特定のキーワードに一致する名前とブランドを持つすべての製品の数を見つける必要があります。

次のようにフリーテキスト「含む」を使用します:

SELECT count(*) 
FROM   Product
       inner join Brand 
         on Product.BrandID = Brand.ID
WHERE  (contains(Product.Name, 'pants') 
   or 
            contains(Brand.Name, 'pants'))

このクエリには約 17秒かかります。 このクエリを実行する前に、FreeTextインデックスを再構築しました。

Product.Nameのみを確認する場合。クエリは1秒未満です。 Brand.Nameのみをチェックする場合も同じです。 OR条件を使用すると問題が発生します。

LIKEを使用するようにクエリを切り替えた場合:

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句の結合テーブル   である結果セットで検索する   2つ以上のテーブルの積。

だから、INNER JOINEDテーブルをFROMに追加しました:

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'でCONTAINSまたはFREETEXT述語を使用できません。

では、質問は-なぜOR条件がクエリの遅延などを引き起こしているのでしょうか?

役に立ちましたか?

解決

ちょっとした試行錯誤の後、私はうまくいくと思われる解決策を見つけました。インデックス付きビューの作成が含まれます。

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'))
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top