SQL请求非常慢,尽管创建了索引
我的SQL-Server上的一些内部连接有一个奇怪的问题。 虽然在内部联接和where子句中使用的所有列都有索引,但速度非常慢 以下是我的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.
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