SQL请求非常慢,尽管创建了索引

SQL请求非常慢,尽管创建了索引,sql,sql-server,performance,Sql,Sql Server,Performance,我的SQL-Server上的一些内部连接有一个奇怪的问题。 虽然在内部联接和where子句中使用的所有列都有索引,但速度非常慢 以下是我的SQL请求: SELECT p.VORNA AS firstName, p.NACHN AS lastName, p.USRID AS [user], o.ORGEH AS OUID, o.STEXT AS OU, a.HolidayDate AS absentFrom, a.

我的SQL-Server上的一些内部连接有一个奇怪的问题。 虽然在内部联接和where子句中使用的所有列都有索引,但速度非常慢

以下是我的SQL请求:

SELECT p.VORNA AS firstName,
       p.NACHN AS lastName,
       p.USRID AS [user],
       o.ORGEH AS OUID,
       o.STEXT AS OU,
       a.HolidayDate AS absentFrom,
       a.HolidayDate AS absentUntil,
       k.MessageDate AS actionDate,
       'holiday' AS reason
FROM Kondor_User_Activities AS k
INNER JOIN dbo.SAP_Personaldaten AS p ON p.USRID = k.Code
INNER JOIN Kondor_Users u ON u.Users_Id = k.Users_Id
INNER JOIN SAP_OE AS o ON p.ORGEH = o.ORGEH
INNER JOIN Kondor_UsersGrp AS g ON g.UsersGrp_Id = u.UsersGrp_Id
INNER JOIN Kondor_Cities AS c ON c.Cities_Id = u.Cities_Id OR (u.Cities_Id IS NULL AND c.Cities_Id = g.Cities_Id)
INNER JOIN Kondor_FixedHolidays AS a ON k.MessageDate >= a.HolidayDate
    AND k.MessageDate < a.HolidayDateEnd
    AND a.Cities_Id = c.Cities_Id
--WHERE g.UsersGrp_ShortName NOT LIKE 'UA_%'
WHERE (g.UsersGrp_ShortName < 'UA_' OR g.UsersGrp_ShortName >= 'UA`')
这也是我的执行计划,我认为错误在Kondor_Users_Activities表中,尽管我在那里有两个索引。也许,聚集索引比非聚集索引更好

试试这个-

CREATE NONCLUSTERED INDEX ix1
ON dbo.Kondor_User_Activities (Code, Users_Id, MessageDate)
GO

SELECT  p.VORNA AS firstName, 
        p.NACHN AS lastName, 
        p.USRID AS [USER], 
        o.ORGEH AS OUID, 
        o.STEXT AS OU, 
        a.HolidayDate AS absentFrom, 
        a.HolidayDateEnd AS absentUntil, 
        k.MessageDate AS actionDate,
        'holiday' as reason
FROM dbo.Kondor_User_Activities k 
JOIN dbo.SAP_Personaldaten p ON p.USRID = k.Code
JOIN dbo.SAP_OE o ON p.ORGEH = o.ORGEH 
JOIN dbo.Kondor_Users u ON u.Users_Id = k.Users_Id 
JOIN dbo.Kondor_UsersGrp g ON g.UsersGrp_Id = u.UsersGrp_Id
JOIN dbo.Kondor_FixedHolidays a ON k.MessageDate >= a.HolidayDate AND k.MessageDate < a.HolidayDateEnd AND a.Cities_Id = g.Cities_Id
WHERE (g.UsersGrp_ShortName < 'UA_' OR g.UsersGrp_ShortName >= 'UA`')
    AND EXISTS(
        SELECT 1
        FROM Kondor_Cities c
        WHERE c.Cities_Id IN (u.Cities_Id, g.Cities_Id)
        --WHERE c.Cities_Id = ISNULL(u.Cities_Id, g.Cities_Id)
    )

我怀疑大部分的减速来自于这种连接内部连接Kondor\u Cities,因为c上的c.Cities\u Id=u.Cities\u Id或u.Cities\u Id为NULL,c.Cities\u Id=g.Cities\u Id。SqlServer不擅长优化或谓词

请尝试以下方法:

SELECT  p.VORNA AS firstName, 
        p.NACHN AS lastName, 
        p.USRID AS [USER], 
        o.ORGEH AS OUID, 
        o.STEXT AS OU, 
        x.HolidayDate AS absentFrom, 
        x.HolidayDate AS absentUntil, 
        k.MessageDate AS actionDate,
        'holiday' as reason
FROM        Kondor_User_Activities AS k 
      INNER JOIN dbo.SAP_Personaldaten AS p ON p.USRID = k.Code
        INNER JOIN Kondor_Users u ON u.Users_Id = k.Users_Id 
          INNER JOIN SAP_OE AS o ON p.ORGEH = o.ORGEH 
            INNER JOIN Kondor_UsersGrp AS g ON g.UsersGrp_Id = u.UsersGrp_Id
              INNER JOIN (
                    SELECT DISTINCT a.HolidayDate, a.HolidayDateEnd, a.Cities_Id
                    FROM Kondor_FixedHolidays AS a
              ) x ON k.MessageDate >= x.HolidayDate and k.MessageDate < x.HolidayDateEnd AND x.Cities_Id IN (u.Cities_Id,g.Cities_Id)
WHERE (g.UsersGrp_ShortName < 'UA_' OR g.UsersGrp_ShortName >= 'UA`')
联接不喜欢或不喜欢 您可以使用isnull删除一个或多个

SELECT p.VORNA AS firstName, 
       p.NACHN AS lastName, 
       p.USRID AS [USER], 
       o.ORGEH AS OUID, 
       o.STEXT AS OU, 
       a.HolidayDate AS absentFrom, 
       a.HolidayDate AS absentUntil, 
       k.MessageDate AS actionDate,
       'holiday' as reason
  FROM Kondor_User_Activities AS k       
  JOIN Kondor_Users AS u 
        ON u.Users_Id = k.Users_Id 
  JOIN Kondor_UsersGrp AS g 
        ON g.UsersGrp_Id = u.UsersGrp_Id 
       and (   g.UsersGrp_ShortName <  'UA_' 
            OR g.UsersGrp_ShortName >= 'UA`')
  JOIN Kondor_Cities AS c 
        ON c.Cities_Id = isnull(u.Cities_Id, g.Cities_Id)
  JOIN Kondor_FixedHolidays AS a 
        ON a.Cities_Id = c.Cities_Id
       AND k.MessageDate >= a.HolidayDate 
       and k.MessageDate <  a.HolidayDateEnd 

  JOIN dbo.SAP_Personaldaten AS p 
        ON p.USRID = k.Code 
  JOIN SAP_OE AS o 
        ON p.ORGEH = o.ORGEH 

作为一个盲目的长搜索-没有表、关系、索引或任何有用的东西,请尝试以下方法:

    SELECT
        UActivities.firstName, 
        UActivities.lastName, 
        UActivities.[USER], 
        UActivities.OUID, 
        UActivities.OU, 
        UserHoliday.HolidayDate AS absentFrom, 
        UserHoliday.HolidayDate AS absentUntil, 
        UActivities.actionDate,
        'holiday' as reason
    FROM (
            SELECT 
                k.MessageDate AS actionDate,
                k.Users_Id,
                k.Code,
                p.VORNA AS firstName, 
                p.NACHN AS lastName, 
                p.USRID AS [USER], 
                o.ORGEH AS OUID, 
                o.STEXT AS OU
            FROM Kondor_User_Activities AS k 
                INNER JOIN dbo.SAP_Personaldaten AS p ON k.Code = p.USRID
                    INNER JOIN SAP_OE AS o ON p.ORGEH = o.ORGEH 
            ) AS UActivities
        INNER JOIN (
            SELECT 
                UserCities.Users_Id,
                a.HolidayDate
            FROM (
                    SELECT 
                        u.Users_Id,
                        ISNULL(u.Cities_Id, g.Cities_Id) AS CityId
                    FROM 
                        Kondor_Users u 
                        INNER JOIN Kondor_UsersGrp AS g ON g.UsersGrp_Id = u.UsersGrp_Id AND (g.UsersGrp_ShortName NOT LIKE 'UA_%')
                    ) AS UserCities
                INNER JOIN Kondor_FixedHolidays AS a ON a.Cities_Id = UserCities.CityId
            ) AS UserHoliday ON UActivities.Users_Id = UserHoliday.Users_Id AND UActivities.actionDate >= UserHoliday.HolidayDate and UActivities.actionDate < UserHoliday.HolidayDateEnd
我不知道我是否正确地点击了所有的列名,但我认为这里的问题是,优化器发疯了,并且因为您的条件的复杂性,我说:我将一次一行测试每个用户活动,看看它是否符合所有其他标准

我的工作是分离查询的逻辑部分-顺序如下: 1.创建用户可以直接指定或从组ISNULLu.cities\u Id、g.cities\u Id继承的所有城市 2.基于从1获得的城市创建所有假日 3.从其他表中使用所需的用户数据连接这些表

看看这个结果——也许最好不要创建UAActivities内部查询,而是将这些表从它连接到UserCities的结果。要确定这一点,我确实需要访问权限,但您可以这样做


运行前检查计划。当涉及到读取时,应该会有很大的不同并且更加平衡。

是否使用了索引,是否可以粘贴执行计划?是否可以添加视觉计划?更容易阅读。你有关于kondor_FixedDate的索引吗?是的。说真的,给我们一个指向.sqlplan文件的链接。假设的和实际的。这不仅更容易,而且在任何人考虑尝试帮助之前,它还包含了更多的信息。此人在对我的答案的评论中表示,即使他的查询耗时超过1小时,他也会在10分钟后中止任何答案。感谢您的所有提示和选择,但它仍在获取行。一旦我有了执行计划,我就会发布它。“我的选择”仍在运行,因此可能需要更长的时间。@user3003944只需添加ix1以避免RID LookupHi,我无法执行sql,因为某些别名不起作用:Msg 4104,级别16,状态1,第1行多部分标识符x.Cities\u Id无法绑定。Msg 4104,级别16,状态1,第1行无法绑定多部分标识符u.Cities\u Id。Msg 4104,级别16,状态1,第1行无法绑定多部分标识符a.HolidayDate。Msg 4104,级别16,状态1,第1行无法绑定多部分标识符a.HolidayDate。现在只有2个错误。Msg 4104,级别16,状态1,第1行无法绑定多部分标识符g.Cities_Id。Msg 4104,级别16,状态1,第1行多部分标识符u.Cities\u Id无法绑定。非常感谢,我会让它运行,因为当sql查询嵌套时我不是很好,我总是要问发生了什么。我只是在大学里学到了如何在没有嵌套内部连接的情况下实现。我会让你知道它是否比以前快。当我创建聚集索引而不是非聚集索引时,您认为我可以摆脱91%的成本吗?这取决于您计划如何使用表中的数据。例如,如果数据经常更新,聚集索引会使表变慢。更多信息请参阅本文。这就是你的问题。。。您的Kondor_用户_活动表有超过700万条记录。。。。尝试添加一个where cause,以便从Kondor_User_Activities表中筛选出尽可能多的记录。在没有某种过滤器的情况下,内部连接700万条记录是一个糟糕的想法…感谢您的解决方案,但它似乎比以前慢了很多。同时,我发现Kondor_Users_Activities表存在问题,虽然我有所有必要的索引,但成本为91%。执行计划在现场的下方。看起来是吗?你让它跑了吗?你说这需要一个多小时,你在发布这个答案20分钟后发布了评论。我在一段时间后停止了它,这是真的-它不应该超过1-2分钟,因为我们没有数百万行。所以你的查询需要一个多小时。您在10分钟内中止了此操作,并得出结论,它似乎比以前慢得多。因此,总结而言,您在没有实际测试它是否更快的情况下放弃了此操作。这不是解决性能问题的好方法。更不用说粗鲁了。非常感谢你的帮助
努力我也要试试。我还考虑过对我的查询进行重新排序,或者更好地说,我已经这样做了,但不是像您提供给我的那样,但人们总是说,重新排序可以帮助,但不需要帮助,因为编译器用它自己的逻辑做所有事情-我收到了这些错误消息,但我将尝试解决它们:Msg 4104,级别16,状态1,第1行无法绑定多部分标识符k.MessageDate、a.HolidayDate、k.MessageDate、a.HolidayDateEnd。最后一行有错误-我已更正它们。现在试试看。
SELECT p.VORNA AS firstName, 
       p.NACHN AS lastName, 
       p.USRID AS [USER], 
       o.ORGEH AS OUID, 
       o.STEXT AS OU, 
       a.HolidayDate AS absentFrom, 
       a.HolidayDate AS absentUntil, 
       k.MessageDate AS actionDate,
       'holiday' as reason
  FROM Kondor_User_Activities AS k       
  JOIN Kondor_Users AS u 
        ON u.Users_Id = k.Users_Id 
  JOIN Kondor_UsersGrp AS g 
        ON g.UsersGrp_Id = u.UsersGrp_Id 
       and (   g.UsersGrp_ShortName <  'UA_' 
            OR g.UsersGrp_ShortName >= 'UA`')
  JOIN Kondor_Cities AS c 
        ON c.Cities_Id = isnull(u.Cities_Id, g.Cities_Id)
  JOIN Kondor_FixedHolidays AS a 
        ON a.Cities_Id = c.Cities_Id
       AND k.MessageDate >= a.HolidayDate 
       and k.MessageDate <  a.HolidayDateEnd 

  JOIN dbo.SAP_Personaldaten AS p 
        ON p.USRID = k.Code 
  JOIN SAP_OE AS o 
        ON p.ORGEH = o.ORGEH 
    SELECT
        UActivities.firstName, 
        UActivities.lastName, 
        UActivities.[USER], 
        UActivities.OUID, 
        UActivities.OU, 
        UserHoliday.HolidayDate AS absentFrom, 
        UserHoliday.HolidayDate AS absentUntil, 
        UActivities.actionDate,
        'holiday' as reason
    FROM (
            SELECT 
                k.MessageDate AS actionDate,
                k.Users_Id,
                k.Code,
                p.VORNA AS firstName, 
                p.NACHN AS lastName, 
                p.USRID AS [USER], 
                o.ORGEH AS OUID, 
                o.STEXT AS OU
            FROM Kondor_User_Activities AS k 
                INNER JOIN dbo.SAP_Personaldaten AS p ON k.Code = p.USRID
                    INNER JOIN SAP_OE AS o ON p.ORGEH = o.ORGEH 
            ) AS UActivities
        INNER JOIN (
            SELECT 
                UserCities.Users_Id,
                a.HolidayDate
            FROM (
                    SELECT 
                        u.Users_Id,
                        ISNULL(u.Cities_Id, g.Cities_Id) AS CityId
                    FROM 
                        Kondor_Users u 
                        INNER JOIN Kondor_UsersGrp AS g ON g.UsersGrp_Id = u.UsersGrp_Id AND (g.UsersGrp_ShortName NOT LIKE 'UA_%')
                    ) AS UserCities
                INNER JOIN Kondor_FixedHolidays AS a ON a.Cities_Id = UserCities.CityId
            ) AS UserHoliday ON UActivities.Users_Id = UserHoliday.Users_Id AND UActivities.actionDate >= UserHoliday.HolidayDate and UActivities.actionDate < UserHoliday.HolidayDateEnd