2013-09-24 8 views
7

Ho riscontrato un problema durante la riscrittura di un processo esistente che utilizza il predicato CONTAINS. Il processo esistente funziona con lo CURSOR, ma è molto lento e si rallenta man mano che vengono inseriti più dati.SQL Server CONTAINS Predicato - utilizzando un valore di colonna come <contiene_condizioni>

Ho fatto un semplice esempio (codice sotto) contenente due tabelle - uno è testo completo indicizzato, e l'altro ha una colonna che identifica una condizione di scegliere CONTAINS righe della prima.

La stored procedure corrente utilizza un CURSOR per scorrere la seconda tabella, impostando una variabile @filter, quindi utilizza CONTAINS per individuare le righe della prima tabella che corrispondono. Il problema è che funziona per ore e sta peggiorando.

Per accelerare il processo, ho provato a utilizzare il predicato CONTAINS direttamente sul valore della colonna anziché passare attraverso il dolore di un cursore ... ma sto ricevendo un errore di sintassi. Il mio esempio è qui sotto.

Ho provato a implementare un CROSS APPLY e ho anche provato a scrivere una funzione definita dall'utente (fnCONTAINS) senza fortuna.

IF (object_id('Players') IS NOT NULL) 
    DROP TABLE Players 

go 

IF (object_id('TeamNeeds') IS NOT NULL) 
    DROP TABLE TeamNeeds 

go 

-- create fulltext catalog ft as default 
go 

CREATE TABLE Players 
    (
    PlayerID  INT IDENTITY(1, 1), 
    PlayerName  VARCHAR(20), 
    PlayerPositions VARCHAR(60) 
) 

go 

CREATE UNIQUE INDEX IXPlayerID 
    ON Players(PlayerID) 

go 

CREATE fulltext INDEX ON Players(PlayerPositions) KEY INDEX IXPlayerID 

go 

INSERT Players 
     (PlayerName, 
     PlayerPositions) 
VALUES('Patrick Travers', 
     'Pitcher,Left Field,Center Field,Right Field,Shortstop') 

go 

CREATE TABLE TeamNeeds 
    (
    TeamID INT, 
    Keywords VARCHAR(50) 
) 

go 

INSERT TeamNeeds 
     (TeamID, 
     Keywords) 
VALUES(1, 
     '"Center Field" and "Shortstop" and "Pitcher"') 

go 

WAITFOR delay '00:00:05' 

go -- Give the Full Text Index process time to populate the catalog 
SELECT PlayerID, 
     PlayerName, 
     PlayerPositions 
FROM Player, 
     TeamNeeds 
WHERE CONTAINS(PlayerPositions, Keywords) 

go -- Syntax error on Keywords... 
SELECT PlayerID, 
     PlayerName, 
     PlayerPositions 
FROM Players, 
     TeamNeeds 
WHERE CONTAINS(PlayerPositions, '"Center Field" and "Shortstop" and "Pitcher"') 

go -- Works just fine, but requires setting an explicit search expression for every search, which is terribly slow 
+0

Ho rimosso il separatore di commenti per rendere il codice più leggibile. – Khan

+0

Ho anche cercato di rispondere a questa domanda. Ho guardato la documentazione di stackoverflow e ms, ma sembra che tu non possa fare CONTAINS (table1.col, table2.col). Puoi solo CONTAINS (table1.col, 'text') o CONTAINS (table1.col, @some_text). Spero che qualcuno venga e mi dimostri che ho torto. – Nico

+0

Hai capito come risolvere questo problema? Sto avendo esattamente lo stesso problema. –

risposta

2

Questo è possibile solo con una TVF a più voci, per quanto posso vedere.

Creare la seguente funzione

CREATE FUNCTION [dbo].[ft_test] (@Keywords VARCHAR(50)) 
RETURNS @ReturnTable TABLE (
    PlayerID  INT, 
    PlayerName  VARCHAR(20), 
    PlayerPositions VARCHAR(60)) 
AS 
    BEGIN 
     INSERT INTO @ReturnTable 
     SELECT PlayerID, 
      PlayerName, 
      PlayerPositions 
     FROM Players 
     WHERE CONTAINS(PlayerPositions, @Keywords) 

     RETURN 
    END 

Poi il seguente funziona bene

SELECT * 
FROM TeamNeeds 
     CROSS APPLY [dbo].[ft_test] (Keywords) CA 

Anche se la versione in linea non riesce con "La funzione inline 'x' non può prendere parametri o Sottointerrogazioni correlate perché utilizza un operatore full-text. "