【问题标题】:SQL Query is taking too long to execute [closed]SQL 查询执行时间过长[关闭]
【发布时间】:2013-05-13 05:48:32
【问题描述】:

您好,以下是我为 SQL 2008 编写的查询。插入 500000 条记录需要 2 个多小时。任何人都可以提出一种提高性能的方法吗?

INSERT INTO tblUserFile
SELECT
    CASE
        WHEN UD.IdentityStatus = 'A' THEN 'ACTIVE'
        WHEN UD.IdentityStatus in ('T','') THEN 'INACTIVE'
        WHEN UD.IdentityStatus IS NULL THEN ''
    END,
    --'UD.IS' AS "Status",
    ISNULL(UD.HltID,'') AS "USERID",
    ISNULL(UD.HltID,'') AS "USERNAME",
    ISNULL(UD.FirstName,'') AS "FIRSTNAME",
    ISNULL(UD.LastName,'') AS "LASTNAME",
    ISNULL(UD.MiddleInitials,'') AS "MI",
    '' AS "GENDER",
    ISNULL(UD.EmailAddress,'') AS "EMAIL",
    CASE
        WHEN SU.UserType = 'C' THEN ISNULL(MCU.Manager, '') ----look into this
        WHEN SU.UserType = 'R' THEN 'From LMS SuperViser'
        WHEN SU.UserType IS NULL OR SU.UserType = ''  THEN ''
    END,
    '' AS HR,
    '' AS "DEPARTMENT",
    '' AS "JOBCODE",
    '' AS "DIVISION",
    ISNULL(UD.Office,'') AS "LOCATION",
    '' AS "TIMEZONE",
    '' AS "HIREDATE",
    ISNULL(UD.Title,'') AS "TITLE",
    ISNULL(UD.StreetAddress,'') AS "ADDR1",
    '' AS "ADDR2",
    ISNULL(UD.City,'') AS "CITY",
    ISNULL(UD.State,'') AS "STATE",
    ISNULL(UD.Zip,'') AS "ZIP",
    ISNULL(UD.CountryCode,'') AS "COUNTRY", 
    '' AS "REVIEW_FREQ",
    '' AS "LAST_REVIEW_DATE",
    ISNULL(UD.EmployeeType,'') AS "Custom01",
    '' AS "Custom02",
    CASE
        WHEN SU.UserType = 'C' THEN '' 
        WHEN SU.UserType = 'R' THEN ISNULL(FSBD.Name,'')
        WHEN SU.UserType IS NULL OR SU.UserType = ''  THEN ''
    END,
    '' AS "Custom04",
    '' AS "Custom05",
    '' AS "Custom06",
    '' AS "Custom07",
    '' AS "Custom08",
    CASE
        WHEN SU.UserType = 'C' THEN 'Corporate'
        WHEN SU.UserType = 'R' THEN 'Hotel'
        WHEN SU.UserType IS NULL OR SU.UserType = ''  THEN ''
    END,
    ISNULL(UD.EmpId,'') AS "Custom11",
    '' AS "Custom13",
    '' AS "Custom14",
    '' AS "Custom15",
    '' AS "PositionCode",
    ISNULL(SU.HomeFacility, '') AS "HomeFacility",
    'NPS' AS PSFlag
FROM Search..UserData UD
    LEFT JOIN Search..ManagerForCorpUsers MCU ------ look into this
    ON MCU.EmpID = UD.EmpId
    AND UD.EmpId != ''
    AND UD.EmpId IS NOT NULL
    LEFT JOIN Search..securityUsers SU ------ look into this
    ON UD.UserId = SU.UserID
    AND UD.UserId != ''
    AND UD.UserId IS NOT NULL
    LEFT JOIN EIS.dbo.NewQueryFilter NQ
    ON SU.HomeFacility = NQ.FCNB
    AND SU.HomeFacility != ''
    AND SU.HomeFacility IS NOT NULL
    LEFT JOIN Facility..fcSubBrandDesc FSBD
    ON NQ.SubBrand = FSBD.SubBrand
    AND NQ.SubBrand != ''
    AND NQ.SubBrand IS NOT NULL
WHERE 
    ISNULL(UD.IdentityStatus,'') NOT IN ('D','U','L')
    AND ISNULL(UD.EmployeeType,'') NOT IN ('O','V','')
    AND ISNULL(UD.HltId,'')  != ''
    AND ISNULL(UD.EmpId,'') NOT IN (SELECT DISTINCT UserId FROM Search..CurrentUserFile)

【问题讨论】:

  • 您是否有关于 MCU.EmpID、UD.EmpId、UD.UserId、SU.UserID、SU.HomeFacility、NQ.FCNB、NQ.SubBrand 和 FSBD.SubBrand 的索引。也在 UD.IdentityStatus、UD.EmployeeType 和 UD.HltId 上?
  • 没有插入的 SELECT 需要多长时间?

标签: sql sql-server performance sql-server-2008


【解决方案1】:

您是否尝试过避免 DISTINCT 查询的内部查询?

Search..CurrentUserFile 的大小是多少??

试试这样的 -

SELECT
....
FROM Search..UserData UD
    ...  -- all your earlier joins as it is
    LEFt JOIN Search..CurrentUserFile CU on (UD.EmpId=CU.UserId)
WHERE
    ... -- all your where clause
    AND CU.UserId IS NULL;--only show results which are not in CurrentUserFile

【讨论】:

    【解决方案2】:

    试试这个 -

    SELECT ...
    FROM (
        SELECT *
        FROM Search.dbo.UserData UD
        WHERE ISNULL(UD.UserId, '') != ''
            AND ISNULL(UD.IdentityStatus, '') NOT IN ('D','U','L')
            AND ISNULL(UD.EmployeeType, '') NOT IN ('O','V','')
            AND ISNULL(UD.HltId, '') != ''
            AND ISNULL(UD.EmpId, '') NOT IN (
                            SELECT DISTINCT UserId 
                            FROM Search.dbo.CurrentUserFile
                        )
    ) UD
    LEFT JOIN Search.dbo.ManagerForCorpUsers MCU ON MCU.EmpID = UD.EmpId
    LEFT JOIN Search.dbo.securityUsers SU ON UD.UserId = SU.UserID
    LEFT JOIN EIS.dbo.NewQueryFilter NQ ON SU.HomeFacility = NQ.FCNB 
        AND ISNULL(SU.HomeFacility, '') != ''
    LEFT JOIN Facility.dbo.fcSubBrandDesc FSBD ON NQ.SubBrand = FSBD.SubBrand 
        AND ISNULL(NQ.SubBrand, '') != '' 
    

    【讨论】:

    • 而且也不要使用“”/''([COLUMN] AS 'COLUMN NAME'),更优选使用方括号作为列名 - [COLUMN] AS [COLUMN NAME]
    【解决方案3】:

    如果您将恢复模型用作事务,它将记录所有内容,“如果您有更多插入发生,您可以使用 BUlk Logged Recovery,并尝试最小化 Case 语句使用 Joins 而不是 LEft Joins 而不是条件

    【讨论】:

      猜你喜欢
      • 2022-12-02
      • 2021-03-13
      • 2019-04-16
      • 1970-01-01
      • 2019-02-07
      • 2019-12-28
      相关资源
      最近更新 更多