0

複雑な検索アルゴリズムから適切な検索結果を得るのに問題があります。当然のことながら、私は FREETEXT を使用する必要がありますが、私は SQL Server にかなり慣れていないため、全文検索インデックスを作成する方法がわかりません。また、サーバーのハード ドライブ容量も不足しています。だから、今持っているものを使わなければならない。データベースのメンバー テーブルには 100 万を超えるエントリがあるため、結果の取得に時間がかかります。

入力例

@CriteriaStr = 'Attorney New York'
@PageSize = 10
@PG = 1

コードを表示させてください:

メイン検索 SQL スクリプト

IF @MODE = 'MEMBER-MAIN-SEARCH'
    BEGIN
        SELECT @TotalPages = CEILING(COUNT(*)/@PageSize)
        FROM Member
        WHERE MemberID IN (SELECT MemberID FROM sbuser.tf_MemberSearchCriteria(REPLACE(@CriteriaStr,' ',',')))
        AND Claimed = 'Y'
        AND Viewable = 'Y';

        WITH MemberSearchResults AS
        (
            SELECT ROW_NUMBER() OVER(ORDER BY a.Claimed DESC) AS RowNum,
            a.MemberID,                                 -- 1    
            a.FirstName,                                -- 2
            a.LastName,                                 -- 3
            a.MemberDisplayName AS DisplayName,         -- 4
            a.UserName,                                 -- 5
            a.LastLogin,                                -- 6
            a.PrCity,                                   -- 7
            a.BusinessName,                             -- 8
            a.ShortDesc,                                -- 9
            a.PrAddr1,                                  -- 10
            a.PrAddr2,                                  -- 11
            a.PrZip,                                    -- 12
            b.Abbr,                                     -- 13
            c.Country,                                  -- 14
            a.AvatarMed,                                -- 15
            a.Gender,                                   -- 16
            d.Domain,                                   -- 17
            a.Claimed,                                  -- 18
            a.PrPhone,                                  -- 19
            a.PrShowAddress,                            -- 20
            a.ProfileTypeID,                            -- 21
            @TotalPages AS TotalPages                   -- 22
            FROM Member a
            RIGHT JOIN State b ON b.StateID = a.PrStateID
            INNER JOIN Country c ON c.CountryID = a.PrCountryID
            INNER JOIN Region d ON d.RegionID = a.MemberRegionID
            WHERE a.MemberID IN (SELECT MemberID FROM sbuser.tf_MemberSearchCriteria(REPLACE(@CriteriaStr,' ',',')))
            AND Claimed = 'Y'
            AND Viewable = 'Y'
        )
        SELECT * 
        FROM MemberSearchResults
        WHERE RowNum BETWEEN (@PG - 1) * @PageSize + 1 AND @PG * @PageSize
        ORDER BY Claimed DESC
    END

TF_MEMBERSEARCHCRITERIA

USE [storeboard]
GO
/****** Object:  UserDefinedFunction [sbuser].[tf_MemberSearchCriteria]    Script Date: 11/30/2012 08:22:34 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER FUNCTION [sbuser].[tf_MemberSearchCriteria](@CriteriaStr varchar(255))
RETURNS @OUT TABLE (MemberID bigint)

AS

BEGIN
    DECLARE @Keyword varchar(150)


    DECLARE CUR CURSOR FOR SELECT Keyword from sbuser.tf_Keywords(@CriteriaStr)
    OPEN CUR
    FETCH NEXT FROM CUR INTO @Keyword
    WHILE @@FETCH_STATUS = 0
        BEGIN
            --INSERT INTO @OUT
            --SELECT MemberID FROM Member WHERE ShortDesc LIKE '%' + @Keyword + '%' AND Claimed = 'Y'  AND MemberID NOT IN (Select MemberID FROM @OUT)

            --INSERT INTO @OUT
            --SELECT MemberID FROM Member WHERE UserName LIKE '%' + @Keyword + '%' AND Claimed = 'Y'  AND memberID NOT IN (Select MemberID FROM @OUT)

            INSERT INTO @OUT
            SELECT MemberID FROM Member WHERE BusinessName LIKE '%' + @Keyword + '%' AND Claimed = 'Y' AND memberID NOT IN (SELECT MemberID FROM @OUT)

            INSERT INTO @OUT
            SELECT MemberID FROM Member WHERE FirstName + LastName LIKE '%' + REPLACE(@Keyword,' ','') + '%' AND Claimed = 'Y' AND memberID NOT IN (SELECT MemberID FROM @OUT)

            INSERT INTO @OUT
            SELECT a.MemberID
            FROM MemberBusinessCat a
            LEFT JOIN BusinessCat b ON b.BusinessCatID = a.BusinessCatID
            LEFT JOIN BusinessCat c ON c.BusinessCatID = b.ParentID
            WHERE b.CategoryName LIKE '%' + @Keyword + '%' OR c.CategoryName LIKE '%' + @Keyword + '%'
            AND a.MemberID NOT IN (SELECT MemberID FROM @OUT)


            FETCH NEXT FROM CUR INTO @Keyword

        END
    CLOSE CUR
    DEALLOCATE CUR


    DELETE FROM @OUT WHERE MemberID IS NULL

    RETURN
END

TF_KEYWORDS

USE [storeboard]
GO
/****** Object:  UserDefinedFunction [sbuser].[tf_Keywords]    Script Date: 11/30/2012 08:50:00 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER FUNCTION [sbuser].[tf_Keywords] 
    (@KeywordList varchar(4000)
)
RETURNS @OUT TABLE (
    Keyword varchar(50))

AS
    BEGIN
        DECLARE @NEXTPOS bigint
        DECLARE @NEXTWORD varchar(50)
        DECLARE @LISTLEN int
        DECLARE @FAILSAFE int

        SET @FAILSAFE = 0

        SET @KeywordList = @KeywordList + ','
        WHILE @KeywordList <> '' AND @FAILSAFE < 50
            BEGIN
                SET @NEXTPOS = CHARINDEX(',',@KeywordList)
                SET @LISTLEN = LEN(@KEYWORDLIST)
                SET @NEXTWORD = LTRIM(RTRIM(REPLACE(LEFT(@KeywordList,@NEXTPOS),',','')))
                SET @KEYWORDLIST = RIGHT(@KEYWORDLIST,@LISTLEN-@NEXTPOS)


                INSERT INTO @OUT
                SELECT @NEXTWORD

                SET @FAILSAFE = @FAILSAFE + 1

            END

    RETURN
    END

任意のメンバーの結果数で TF_MEMBERSEARCHRITERIA を注文できるかどうか疑問に思っていました。メンバーは弁護士によってニューヨークにいる可能性があり、結果に 3 回表示されます。スクリプトは繰り返しを削除しますが、3 つの結果を数えてから、DESC オーダーで並べ替える方法はありますか?

私はまだ比較的新しいので、SQL の複雑な部分をまだ完全には理解していません。

よろしくお願いします、neojakey

4

1 に答える 1

1

こんにちは、私はこれについて大きな答えを出しています。申し訳ありませんが、間違いがあれば教えてください。改善領域にコメントしました

アドバイス 1 :-
1) インデックス付きビューを使用し、検索可能な列を 1 つの coumn に追加します。たとえば、列 memberID をプライマリとして持つ必要があり、検索テキスト nvarchar(MAX) が必要です -- exm のようなすべての検索 coumns を追加します
-- FirstName + LastName + BusinessName 2) フルテキスト インデックスを作成しますその上で、部分的な単語検索または結果のランキング順序のために contains を使用します freetextable クエリを作成する方法を大いに助けることができます
3) ディスク容量が少ない場合は、簡単でシンプルです

アドバイス 2 :- 1) 最後の 10 行のみにすべての結合を使用します。INTHEMO_認証コード

  ;    WITH 
    MemberSearchResults AS
        (
            SELECT ROW_NUMBER() OVER(ORDER BY a.Claimed DESC) AS RowNum,
           a.MemberID,  ----   bring  the primary  and  the columns need to  orderby  only  dont join  with unnessary tables inthis step 
           a.Claimed

            FROM Member a
            --RIGHT JOIN State b ON b.StateID = a.PrStateID
            --INNER JOIN Country c ON c.CountryID = a.PrCountryID
            --INNER JOIN Region d ON d.RegionID = a.MemberRegionID
            WHERE a.MemberID IN (SELECT MemberID FROM sbuser.tf_MemberSearchCriteria(REPLACE(@CriteriaStr,' ',','))  group by MemberID)
    ----  in that   function   dont use like --NOT IN (SELECT MemberID FROM @OUT)     its a small improvement  u can do here 
            AND Claimed = 'Y'    ----  ur checking this condition  on function tooo  then no need here  i think 
            AND Viewable = 'Y'  ----  ur checking this condition  on function tooo  then no need here  i think 
        )
        SELECT   --a.MemberID,                                 -- 1    
            --a.FirstName,                                -- 2
            --a.LastName,                                 -- 3
            --a.MemberDisplayName AS DisplayName,         -- 4
            --a.UserName,                                 -- 5
            --a.LastLogin,                                -- 6
            --a.PrCity,                                   -- 7
            --a.BusinessName,                             -- 8
            --a.ShortDesc,                                -- 9
            --a.PrAddr1,                                  -- 10
            --a.PrAddr2,                                  -- 11
            --a.PrZip,                                    -- 12
            --b.Abbr,                                     -- 13
            --c.Country,                                  -- 14
            --a.AvatarMed,                                -- 15
            --a.Gender,                                   -- 16
            --d.Domain,                                   -- 17
            --a.Claimed,                                  -- 18
            --a.PrPhone,                                  -- 19
            --a.PrShowAddress,                            -- 20
            --a.ProfileTypeID,                            -- 21
            --@TotalPages AS TotalPages                   -- 22
        FROM MemberSearchResults cross join (SELECT  COUNT(*) FROM MemberSearchResults) AS @TotalPages --  u have to do total page count like this 
          --RIGHT JOIN State b ON b.StateID = a.PrStateID
            --INNER JOIN Country c ON c.CountryID = a.PrCountryID
            --INNER JOIN Region d ON d.RegionID = a.MemberRegionID
        WHERE RowNum BETWEEN (@PG - 1) * @PageSize + 1 AND @PG * @PageSize 
        ORDER BY Claimed DESC

最後に、dity 読み取りに問題がない場合は nolock を使用できます。

于 2012-11-30T20:35:19.730 に答える