使用JOIN在PATINDEX上进行性能调优

时间:2018-12-17 06:51:56

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

我有一个名为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

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

1 个答案:

答案 0 :(得分:1)

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

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

我将建议修改表并检查数据是否可以进一步规范化。在某些情况下,这可以提高性能,并减少表存储空间。

例如,可以将zipcode移到单独的表中,而可以使用zipcode字符串来代替整数列。尝试进一步规范化地址-如果您有城市,街道或街区,街道或街区编号?名称-如果您需要按名字搜索,姓氏只需将名称分成不同的列即可。

对于字符串值,可以清除数据-例如,删除开头和末尾(trim)的空字符串。有了这些数据,我们可以创建哈希索引并获得非常快速的均等搜索。

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