提高sql server的搜索性能?

时间:2016-06-08 05:47:54

标签: sql-server performance

我在SQL server下面的表中存储了所有国家/地区的数据。 我写了一个查询,通过查找邮政编码和国家

获取城市和县
    ALTER PROCEDURE [dbo].[SPCleanAddresses]
AS
BEGIN


DECLARE @tableName NVARCHAR(100);
DECLARE @separator NVARCHAR(3);
SET @tableName = 'UKUNMATCHDATA_Version1_ten';
SET @separator = ' ';
--AS


BEGIN
    DECLARE @TableCleanedName NVARCHAR(100);

    SET @TableCleanedName = CONCAT(@tableName, '_DataCleaned');
    SET NOCOUNT ON;
    IF EXISTS
    (
        SELECT name
        FROM sysobjects
        WHERE Name = 'data'
    )
        BEGIN
            DROP TABLE dbo.data;
        END;
    IF EXISTS
    (
        SELECT name
        FROM sysobjects
        WHERE Name = 'DataCleaned_Version1'
    )
        DROP TABLE DataCleaned_Version1;
     EXEC ('select * into data  from '+@tableName+'');
     SELECT 

              CASE
                    WHEN i.Zipcode IS NOT NULL AND i.COUNTRY IS NOT NULL
                    THEN UPPER([dbo].[fnGetCityfromZipCode](i.Zipcode, i.[COUNTRY]))
                    ELSE NULL
                END AS City,
             CASE
                    WHEN i.Zipcode IS NOT NULL AND i.COUNTRY IS NOT NULL
                    THEN UPPER([dbo].[fnGetCountyfromZipCode](i.Zipcode, i.[COUNTRY]))
                    ELSE NULL
                END AS County,
             i.*

    INTO DataCleaned_Version1
    FROM
    (
          SELECT h.*   ,      CASE
                             WHEN h.[post-code] <> ('') AND h.[post-code] IS NOT NULL THEN REPLACE(REPLACE(LTRIM(RTRIM(h.[POST-CODE])),' ',''),'-','')
                             ELSE [dbo].[udf_fnLookupZipCodeAndFindCityCounty](h.Number1,h.Number2,h.Number3,h.Number4,h.Number5,h.Number6,h.Number7,h.[COUNTRY])
                          END AS Zipcode
          FROM
          (
             SELECT g.*,
                          CASE
                                WHEN dbo.udf_ExtractInteger(LTRIM(RTRIM(SUBSTRING(g.address11, 0, LEN(g.address11)+1)))) <> ''
                                THEN dbo.udf_ExtractInteger(LTRIM(RTRIM(SUBSTRING(g.address11, 0, LEN(g.address11)+1))))
                          END AS Number6,
                          CASE
                                WHEN dbo.udf_ExtractInteger(LTRIM(RTRIM(SUBSTRING(g.address12, 0, LEN(g.address12)+1)))) <> ''
                                THEN dbo.udf_ExtractInteger(LTRIM(RTRIM(SUBSTRING(g.address12, 0, LEN(g.address12)+1))))
                          END AS Number7          
             FROM
             (

                 SELECT f.*,
                          LTRIM(RTRIM(SUBSTRING(f.address10, 0, CHARINDEX(@separator, f.address10)))) AS address11,
                            CASE
                                WHEN dbo.udf_ExtractInteger(LTRIM(RTRIM(SUBSTRING(f.address9, 0, LEN(f.address9)+1)))) <> ''
                                THEN dbo.udf_ExtractInteger(LTRIM(RTRIM(SUBSTRING(f.address9, 0, LEN(f.address9)+1))))
                            END AS Number5,
                            LTRIM(RTRIM(SUBSTRING(f.address10, CHARINDEX(@separator, f.address10)+1, 8000))) AS address12
                    FROM
                    (

                    SELECT e.*,
                             LTRIM(RTRIM(SUBSTRING(e.address8, 0, CHARINDEX(@separator, e.address8)))) AS address9,
                                CASE
                                   WHEN dbo.udf_ExtractInteger(LTRIM(RTRIM(SUBSTRING(e.address7, 0, LEN(e.address7)+1)))) <> ''
                                   THEN dbo.udf_ExtractInteger(LTRIM(RTRIM(SUBSTRING(e.address7, 0, LEN(e.address7)+1))))
                                END AS Number4,
                                LTRIM(RTRIM(SUBSTRING(e.address8, CHARINDEX(@separator, e.address8)+1, 8000))) AS address10
                    FROM
                    (

                       SELECT d.*,
                                LTRIM(RTRIM(SUBSTRING(d.address6, 0, CHARINDEX(@separator, d.address6)))) AS address7,
                                CASE
                                   WHEN dbo.udf_ExtractInteger(LTRIM(RTRIM(SUBSTRING(d.address5, 0, LEN(d.address5)+1)))) <> ''
                                   THEN dbo.udf_ExtractInteger(LTRIM(RTRIM(SUBSTRING(d.address5, 0, LEN(d.address5)+1))))
                                END AS Number3,
                                LTRIM(RTRIM(SUBSTRING(d.address6, CHARINDEX(@separator, d.address6)+1, 8000))) AS address8
                          FROM
                          (
                             SELECT c.*,
                                   LTRIM(RTRIM(SUBSTRING(c.address4, 0, CHARINDEX(@separator, c.address4)))) AS address5,
                                   CASE
                                      WHEN dbo.udf_ExtractInteger(LTRIM(RTRIM(SUBSTRING(c.address1, 0, LEN(c.address1)+1)))) <> ''
                                      THEN dbo.udf_ExtractInteger(LTRIM(RTRIM(SUBSTRING(c.address1, 0, LEN(c.address1)+1))))
                                   END AS Number1,
                                   CASE
                                      WHEN dbo.udf_ExtractInteger(LTRIM(RTRIM(SUBSTRING(c.address3, 0, LEN(c.address3)+1)))) <> ''
                                      THEN dbo.udf_ExtractInteger(LTRIM(RTRIM(SUBSTRING(c.address3, 0, LEN(c.address3)+1))))
                                   END AS Number2,
                                   LTRIM(RTRIM(SUBSTRING(c.address4, CHARINDEX(@separator, c.address4)+1, 8000))) AS address6
                             FROM
                             (
                                SELECT b.*,
                                      LTRIM(RTRIM(SUBSTRING(b.aaddress2, 0, CHARINDEX(@separator, b.aaddress2)))) AS address3,
                                      LTRIM(RTRIM(SUBSTRING(b.aaddress2, CHARINDEX(@separator, b.aaddress2)+1, 8000))) AS address4
                                FROM
                                (
                                    SELECT a.*,
                                         LTRIM(RTRIM(SUBSTRING(a.address, 0, CHARINDEX(@separator, a.address)))) AS address1,
                                         LTRIM(RTRIM(SUBSTRING(a.address, CHARINDEX(@separator, a.address)+1, 8000))) AS aaddress2
                                    FROM data AS a
                                ) AS b
                             ) AS c
                       ) AS d
                    )AS e
                )f
             )g
             )h
    )i
END;
 END

但是在我的源表中我有68,000条记录,但只需用10条记录执行此查询需要13秒

到目前为止,我已应用非聚集索引

CREATE NONCLUSTERED INDEX ix_people_lastname

ON dbo.AllCountriesZipCode(ZipCode,County)

WITH (fillfactor=80);

GO

但我仍然得到相同的结果(13秒)仅10个记录

这方面的任何帮助都是合适的,请注意邮政编码有重复的值,

我的功能是从此表中的邮政编码和国家/地区查找城市和县。

请帮助我,我需要解决这个问题,对于我的源表上的68000条记录,它需要超过8小时,因为每条记录在所有国家的密码表中传输大约98000条记录

enter image description here

1 个答案:

答案 0 :(得分:1)

如果我在你的位置,我从底部开始。

EXEC ('select * into data  from '+@tableName+'');

高于 @tableName 的值的查询必须处于另一个隔离级别。如果表格中的数据不是非常敏感,您可以使用 WITH(NOLOCK) 提示( READ UNCOMMITTED 隔离级别)。否则,请使用 SNAPSHOT

示例:

EXEC ('select * into data  from '+@tableName+' WITH(NOLOCK)');

衡量您的查询执行时间,如果仍然不够,请查看上面的 SELECTs 。 一步一步做。尝试从底部到顶部删除所有查询逻辑,并逐步添加查找执行时间。