【问题标题】:Performance tuning on PATINDEX with JOIN使用 JOIN 对 PATINDEX 进行性能调整
【发布时间】:2019-05-17 12:32:16
【问题描述】:

我有一个名为 tbl_WHO 的表,有 9000 万条记录,而临时表 #EDU 只有 5 条记录。

我想对两个表(tbl_WHO#EDU)之间的名称字段进行模式匹配。

查询:以下查询需要 00:02:13 时间执行

SELECT  Tbl.PName,Tbl.PStatus     
FROM tbl_WHO Tbl 
INNER JOIN #EDU Tmp 
ON 
(
    (ISNULL(PATINDEX(Tbl.PName,Tmp.FirstName),'0')) > 0 
)    

有时我必须对多个列进行模式匹配,例如:

SELECT  Tbl.PName,Tbl.PStatus     
FROM tbl_WHO Tbl 
INNER JOIN #EDU Tmp 
ON 
(
    (ISNULL(PATINDEX(Tbl.PName,Tmp.FirstName),'0')) > 0 AND
    (ISNULL(PATINDEX('%'+Tbl.PAddress+'%',Tmp.Addres),'0')) > 0 OR
    (ISNULL(PATINDEX('%'+Tbl.PZipCode,Tmp.ZCode),'0')) > 0  
)    

注意:有INDEX创建在条件列上。

还有其他方法可以调整查询性能吗?

【问题讨论】:

    标签: sql-server tsql sql-server-2008-r2 query-performance


    【解决方案1】:

    % 开头的搜索不是sargable,因此即使在给定列上有索引,您也无法有效地使用它。

    您确定每次都需要使用PATINDEX 进行搜索吗?包含 9000 万条记录的表并不大,但列多且未正确应用规范化肯定会降低性能。

    我会建议修改表格并检查数据是否可以进一步规范化。这可以在特定情况下提高性能并减少表存储。

    例如,zipcode 可以移动到分隔表,而不是使用zipcode 字符串,您可以按整数列连接。尝试进一步规范化地址 - 如果您有城市、街道或街区、街道或街区号?姓名 - 如果您需要按名字搜索,只需将姓名分成不同的列。

    对于字符串值,可以对数据进行清理 - 例如,在请求和结尾(修剪)处删除空字符串。有了这样的数据,我们就可以创建哈希索引并获得极快的相等搜索。

    我想说的是,如果您对数据进行规范化并添加一些规则(在数据库和应用程序级别)以确保输入数据正确,您将获得非常好的性能。这是很长的路要走,但你要做到这一点——现在做起来比以后做起来容易(你现在迟到了)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-07-23
      • 1970-01-01
      • 1970-01-01
      • 2017-08-29
      • 2019-08-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多