使用具有附加条件的全文搜索来搜索1300万条记录

使用其他条件执行SQL Server全文搜索时出现性能问题。 (SQL Server 2012)使用具有附加条件的全文搜索来搜索1300万条记录

我想根据搜索过滤器列表(表值参数)过​​滤数据,它将返回匹配过滤器的所有记录,并且过滤器的单个记录没有表中的任何记录。

对于列SNAME,全文搜索索引已经在表Names上。

在存储过程中,表类型参数SearchFilter用于传递名称和地址信息列表。

这两个表都有超过1400万条记录,当我们在过滤器列表中传递1000个唯一记录并执行该过程时,大约需要7分钟才能返回结果(1400条记录)。

过滤标准是:包含(名称)和streetaddress,城市,州,邮编完全匹配。

是否有任何替代避免while循环为SQL Server CONTAINS函数所需的字符串值或变量?

CREATE TABLE [dbo].[Names] 

(

[ID] [int] IDENTITY(1,1) NOT NULL,

[UIN] [varchar](9) NULL,

[SNAME] [varchar](500) NULL,

CONSTRAINT [PK_Names]

PRIMARY KEY CLUSTERED ([ID] ASC)

)

CREATE TABLE [dbo].[ADDRESSES]

(

[UIN] [varchar](9) NULL,

[STREET1] [varchar](100) NULL,

[STREET2] [varchar](50) NULL,

[CITY] [varchar](30) NULL,

[STATE] [varchar](2) NULL,

[ZIP] [varchar](10) NULL

) ON [PRIMARY]

CREATE TYPE [dbo].[SearchFilter] AS TABLE

(

[UIN] [varchar](40) NULL,

[SNAME] [varchar](max) NULL,

[StreetAddress] [varchar](max) NULL,

[City] [varchar](max) NULL,

[State] [varchar](50) NULL,

[Zip] [varchar](20) NULL

)

-- Stored procedure logic

DECLARE @filterList AS [dbo].[SearchFilter]

DECLARE @NoOfRows INT, @counter INT = 0

SET @NoOfRows = (SELECT COUNT(1) FROM @filterList)

DECLARE @result TABLE (UIN varchar(40),

NAME varchar(500),

StreetAddress varchar(1000),

Zipcode varchar(20),

State varchar(20),

City varchar(1000),

IsRecordFound varchar(50)

);

WHILE (@NoOfRows > @counter)

BEGIN

DECLARE @SearchName VARCHAR(4000)

SET @SearchName = (SELECT '"'+SNAME+'"' FROM @filterList ORDER BY SNAME OFFSET @counter ROWS FETCH NEXT 1 ROWS ONLY)

--Start: Process to Select Records

;WITH Filter_CTE AS

(

SELECT

SNAME, StreetAddress, City, State, ZipCode

FROM

@filterList

ORDER BY

SNAME

OFFSET @counter ROWS FETCH NEXT 1 ROWS ONLY

)

INSERT INTO @result (UIN, NAME, STREETADDRESS, CITY, STATE, ZIPCODE, PHONE, IsRecordFound)

SELECT DISTINCT

en.UIN, ISNULL(en.SNAME, Filter_CTE.SNAME),

Filter_CTE.StreetAddress, Filter_CTE.ZipCode,

Filter_CTE.state, Filter_CTE.City,

IIF(en.UIN IS NULL, 'Not Found', 'Found') AS IsRecordFound

FROM

dbo.Names en

INNER JOIN

dbo.ADDRESSES ea ON en.UIN = ea.UIN

RIGHT JOIN

Filter_CTE ON ea.ZIP = Filter_CTE.Zip

AND ea.STATE = Filter_CTE.State

AND ea.CITY = Filter_CTE.City

AND (ISNULL(ea.STREET1, '') + ' ' + ISNULL(ea.STREET2, '')) = Filter_CTE.StreetAddress

AND CONTAINS(en.SNAME,@SearchName)

--END

SET @counter += 1

END

SELECT

UIN, NAME, STREETADDRESS, CITY, STATE, ZIPCODE, PHONE

FROM

@result

回答:

目前,它是不可能在CONTAINS或CONTAINSTABLE使用列名作为搜索条件。因此,在应用了FTS谓词的数据表和SearchFilter表之间不能执行直接JOIN

当前在其他问题/论坛中找到的解决方案是循环访问过滤器列表并在搜索条件的变量中输入CONTAINS,就像您一样。所以,你不会摆脱这个循环。

然而,看着你的查询我看到了一些可能会影响性能的其他问题:在INSERT INTO @result ... SELECT DISTINCT ...

  1. DISTINCT条款。它是在你的JOIN到有数百万记录的表的级别。虽然我明白,最后的结果可能只包含几千行,最好是移动DISTINCT这一行:

    SELECT DISTINCT 

    UIN, NAME, STREETADDRESS, CITY, STATE, ZIPCODE, PHONE

    FROM

    @result

  2. 这种情况AND (ISNULL(ea.STREET1, '') + ' ' + ISNULL(ea.STREET2, '')) = Filter_CTE.StreetAddress肯定不是优化搜索。您使用连接和函数(ISNULL()),它可以防止SQL Server通过dbo.ADDRESSES ea表使用现有索引。检查这个问题:What makes a SQL statement sargable?看看如何构建JOIN/WHERE条件,以便允许使用索引。 在这种特定的情况下最好是一计算列添加到dbo.Addresses表,然后生成在其上的索引(或将其添加到现有的索引):

    CREATE TABLE [dbo].[ADDRESSES] 

    (

    ...

    STREET as (ISNULL(ea.STREET1, '') + ' ' + ISNULL(ea.STREET2, '')),

    ...

    )

所以固定上述1然后在RIGHT JOIN中注释AND CONTAINS(en.SNAME,@SearchName)条件并注意执行时间。之后,取消注释CONTAINS的条件并查看添加了多少延迟。通过这种方式,您肯定会知道FTS引擎是否因延迟而受到责备,或者您的主查询本身需要改进。

为了能够提供更多建议,我们需要查看您的过程的执行计划。您可以使用此页面共享您的查询执行计划:https://www.brentozar.com/pastetheplan/。

HTH

以上是 使用具有附加条件的全文搜索来搜索1300万条记录 的全部内容, 来源链接: utcz.com/qa/264750.html

回到顶部