Frage

Ich habe zwei Tabellen:

**Product**
ID
Name
SKU

**Brand**
ID
Name

Produkt Tabelle hat über 120K Datensätze Marke Tabelle hat 30K Aufzeichnungen

Ich brauche Anzahl aller Produkte zu finden, mit Namen und die Marke ein bestimmtes Schlüsselwort entsprechen.

Ich benutze Freitext 'enthält' wie folgt aus:

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

Diese Abfrage dauert etwa 17 Sek. Ich baute den Freetext-Index, bevor Sie diese Abfrage ausgeführt wird.

Wenn ich nur für Product.Name überprüfen. Sie Abfrage ist weniger als 1 Sekunde. Gleiche, wenn ich nur die Brand.Name überprüfen. Das Problem tritt auf, wenn ich verwende ODER-Bedingung.

Wenn ich wechseln Abfrage LIKE zu verwenden:

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

Es dauert 1 Sek.

Ich lese auf MSDN, dass: http://msdn.microsoft.com /en-us/library/ms187787.aspx

  

Um auf mehrere Tabellen zu suchen, verwenden Sie ein   verknüpfte Tabelle in Ihrer FROM-Klausel   Suche auf einer Ergebnismenge, die das ist   Produkt von zwei oder mehreren Tabellen.

So habe ich eine innere verbundene Tabelle 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') 

Dies führt zu Fehler: Kann kein ENTHÄLT oder FREETEXT- Prädikat auf Spalte ‚Product‘ verwenden, weil es nicht volltextindiziert ist.

Die Frage ist also - warum ODER-Bedingung wie langsame Abfrage verursacht sein könnte

War es hilfreich?

Lösung

Nach einem wenig Versuch ein Fehler fand ich eine Lösung, die zu funktionieren scheint. Es geht um eine indizierte Sicht zu erstellen:

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

Wenn ich die folgende Abfrage:

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'))

Es dauert jetzt 1 s wieder.

Andere Tipps

Haben Sie versucht, so etwas wie:

SELECT count(*) 
    FROM Product
    INNER JOIN Brand ON Product.BrandID = Brand.ID
    WHERE CONTAINS((Product.Name, Brand.Name), 'pants') 

Ich lief in ein ähnliches Problem, aber ich regelte es mit Union, so etwas wie:

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'))
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top