0

我在从复杂的搜索算法中获得良好的搜索结果时遇到问题。可以理解,我应该使用 FREETEXT,但我对 SQL Server 还很陌生,我不知道如何创建全文搜索索引,而且服务器的硬盘空间也不足。所以,我必须使用我现在拥有的东西。数据库成员表有超过一百万个条目,因此检索结果很慢。

示例输入

@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_MEMBERSEARCHCRITERIA。会员可以通过律师并且在纽约,这将使他们在结果中显示 3 次。该脚本删除重复,但是否有办法计算 3 个结果,然后按 DESC 顺序排序。

我还比较新,所以我还没有完全理解 SQL 的复杂部分,所以请放轻松。

非常感谢,neojakey

4

1 回答 1

1

嗨,如果有任何错误让我知道我评论了改进区域,我对此很抱歉

Advice1 :-
1) 使用索引视图并将可搜索列添加到 1 个列中,例如您必须将列 memberID 作为主要列,并且 searchtext nvarchar(MAX) -- 添加所有搜索列,如 exm
-- FirstName + LastName + BusinessName 2) 创建全文索引在它上面并使用 contains 进行部分单词搜索或对结果进行排序 freetextable 您可以在如何编写查询方面提供很多帮助
3) 如果您提供较小的磁盘空间,它就简单易行

Advice2 :- 1) 仅对最后 10 行使用所有连接。INTHEMO_Authentication 你的代码

  ;    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 回答