查询大(数百万)数据更快

时间:2016-02-29 21:47:46

标签: sql-server tsql

我有两张桌子:

  • Tbl1有2列:名称和州

  • Tbl2有关于字段的名称和状态以及其他列

我正在尝试将tbl1名称和状态与tbl2名称和状态进行匹配。我已删除所有完全匹配,但我发现如果我可以通过使用比较2个名称的标量函数来解释拼写错误和名称变化,我可以匹配更多,并返回一个整数,显示它们的匹配程度(低于数字返回越好匹配)。

问题是Tbl1有超过2M的记录而Tbl2有超过4M的记录 - 从Tbl2中的Tbl1搜索一条记录需要大约30秒。

我是否可以通过某种方式安排数据或查询,以便更快地完成搜索?

这是表结构:

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

2 个答案:

答案 0 :(得分:0)

一种可能性是添加一个标准化名称的列,仅用于匹配目的。您将删除所有空格,删除重音符号,用缩写的名字替换名字,用实名替换已知的昵称等。

您甚至可以按字母顺序对一个人的名字和姓氏进行排序,以便交换两者。

然后您可以通过此规范化名称列简单地连接两个表。

答案 1 :(得分:0)

JOIN    dbo.Tbl2 t1
  ON    t1.State = t2.State

您将在最多50个不同的值连接条件上加入2Mx4M行。难怪这很慢。你需要回到绘图板并重新定义你的问题。如果你真的想弄清楚'密切匹配' 每个人其他所有人在同一个州,然后准备付出代价......