Sql server 更快地查询大型(以百万计)数据
我有两张桌子:Sql server 更快地查询大型(以百万计)数据,sql-server,tsql,Sql Server,Tsql,我有两张桌子: Tbl1有两列:名称和状态 Tbl2具有名称和状态以及关于字段的附加列 我正在尝试将tbl1名称和状态与tbl2名称和状态匹配。我已经删除了所有精确匹配项,但我发现如果我可以使用一个标量函数来解释拼写错误和名称变化,那么我可以进行更多匹配,该函数比较两个名称,并返回一个整数,显示它们之间的匹配程度(数字越小,匹配效果越好) 问题在于Tbl1有超过200万条记录,而Tbl2有超过400万条记录——从Tbl2中的Tbl1中搜索一条记录大约需要30秒 我是否有办法安排数据或查询,以
- Tbl1有两列:名称和状态
- Tbl2具有名称和状态以及关于字段的附加列
CREATE TABLE Tbl1
(
Id INT NOT NULL IDENTITY( 1, 1 ) PRIMARY KEY,
Name NVARCHAR(255),
[State] VARCHAR(50),
Phone VARCHAR(50),
DoB SMALLDATETIME
)
GO
CREATE INDEX tbl1_Name_indx ON dbo.Tbl1( Name )
GO
CREATE INDEX tbl1_State_indx ON dbo.Tbl1( [State] )
GO
CREATE TABLE Tbl2
(
Id INT NOT NULL IDENTITY( 1, 1 ) PRIMARY KEY,
Name NVARCHAR(255),
[State] VARCHAR(50)
)
GO
CREATE INDEX tbl2_Name_indx ON dbo.Tbl1( Name )
GO
CREATE INDEX tbl2_State_indx ON dbo.Tbl1( [State] )
GO
下面是一个示例函数,我用它进行了测试,试图排除函数的复杂性:
CREATE FUNCTION [dbo].ScoreHowCloseOfMatch
(
@SearchString VARCHAR(200) ,
@MatchString VARCHAR(200)
)
RETURNS INT
AS
BEGIN
DECLARE @Result INT;
SET @Result = 1;
RETURN @Result;
END;
以下是一些示例数据:
INSERT INTO Tbl1
SELECT 'Bob Jones', 'WA', '555-333-2222', 'June 10, 1971' UNION
SELECT 'Melcome T Homes', 'CA', '927-333-2222', 'June 10, 1971' UNION
SELECT 'Janet Rengal', 'WA', '555-333-2222', 'June 10, 1971' UNION
SELECT 'Matt Francis', 'TN', '234-333-2222', 'June 10, 1971' UNION
SELECT 'Same Bojen', 'WA', '555-333-2222', 'June 10, 1971' UNION
SELECT 'Frank Tonga', 'NY', '903-333-2222', 'June 10, 1971' UNION
SELECT 'Jill Rogers', 'WA', '555-333-2222', 'June 10, 1971' UNION
SELECT 'Tim Jackson', 'OR', '757-333-2222', 'June 10, 1971'
GO
INSERT INTO Tbl2
SELECT 'BobJonez', 'WA' UNION
SELECT 'Malcome X', 'CA' UNION
SELECT 'Jan Regal', 'WA'
GO
问题是:
WITH cte as (
SELECT t1Id = t1.Id ,
t1Name = t1.Name ,
t1State = t1.State,
t2Name = t2.Name ,
t2State = t2.State ,
t2.Phone ,
t2.DoB,
Score = dbo.ScoreHowCloseOfMatch(t1.Name, t2.Name)
FROM dbo.Tbl1 t2
JOIN dbo.Tbl2 t1
ON t1.State = t2.State
)
SELECT *
INTO CompareResult
FROM cte
ORDER BY cte.Score ASC
GO
一种可能是添加一个列,其规范化名称仅用于匹配目的。你可以删除所有的空格,删除重音,用缩写的名字替换名字,用真名替换已知的昵称等等 您甚至可以按字母顺序对一个人的名字和姓氏进行排序,以允许两者进行交换 然后,您可以通过这个规范化名称列简单地连接这两个表
JOIN dbo.Tbl2 t1
ON t1.State = t2.State
您正在按照最多50个不同的值联接条件联接2Mx4M行。难怪这么慢。你需要回到绘图板,重新定义你的问题。如果您真的想找出每个人与处于同一状态的其他人的“密切匹配”,那么请准备付出代价……尝试从查询中删除标量函数ScoreHowCloseOfMatch。我怀疑这就是罪魁祸首。标量函数对性能很糟糕。取决于该函数的功能,它可以重写许多方法来提供相当大的帮助。两个过程如何?首先给每个表一个Soundex分数或类似的分数,然后加入它?你能让你的测试函数有nvarchar作为参数,即与表相同并重新运行吗?转换是昂贵的。很好的一点-这实际上是我为精确匹配所做的(我应该提到这一点)。我希望通过评分获得更多的匹配。区别在于,在插入和更新单个记录时会发生规范化,而as评分必须在查询过程中发生,因为您是在比较成对的记录。有很多可能的对:n*m(两个表的记录数的乘积)。