我一直在努力解决这个问题,在某些情况下,sql需要花费30多分钟才能在current
的100k行的表上执行,而大约10是pending
。这是我认为是罪魁祸首的较大连接语句的一部分。基本上,sql的目的是对current
行和pending
行的副本进行排序,以便所有挂起的行位于顶部或底部。它是变革框架管理的一部分。任何想法如何在一个表现稳定的男性中完成?对于某些情况下的记录,在具有10M行和100个挂起更改的表上,相同的sql在10秒内运行。排序是在计算字段上完成的,这个问题更加复杂。数据库是ms sql server 2008 R2。
更新:我正在添加其余的联接,以表明疯狂有半原因。
此处的唯一目的是获取当前记录和待处理记录的组合,以显示未来表格在批准更改后的样式,排序以便更改显示在顶部或底部(ASC或DSC)在hasPending上,额外的Current2连接是添加一些额外的识别数据。
一般来说,它会做它应该做的事情,相当不错的几秒响应时间,10当达到大约10M记录时,然而在少数情况下,一切都会慢慢地爬行,响应时间达到12-30分钟。
WITH [ResultPage] AS
SELECT
ROW_NUMBER() OVER
(ORDER BY
CASE WHEN [Current].[ID] IN
(SELECT [CID]
FROM [Pending] AS p
INNER JOIN [Current] ON [Current].[ID] like p.[CID]
WHERE (p.[User] = 'admin'))
THEN 1
ELSE 0
END ASC,
[Current].[ID] ASC) AS [RowID],
[Current].[ID],
CASE WHEN [Current].[ID] IN
(SELECT [CID]
FROM [Pending] AS p
INNER JOIN [Current] ON [Current].[ID] like p.[CID]
WHERE (p.[User] = 'admin'))
THEN 1
ELSE 0
END AS [HasPending]
FROM [Current]
INNER JOIN [Current2] AS [Table2] ON ([Current].[T2ID] = [Table2].[ID])
SELECT [ResultPage].[RowID], [ResultPage].[HasPending], [Current2].[ID] As [Current2^ID], [Tag].Name],
etc... etc...
FROM [ResultPage]
INNER JOIN [Current] ON ([Current].[ID] = [ResultPage].[ID])
INNER JOIN [Current2] ON ([Current].[T2ID] = [Current2].[ID])
WHERE (([ResultPage].[RowID] BETWEEN -1 AND 50)) ORDER BY [ResultPage].[RowID] ASC
答案 0 :(得分:2)
我猜有一个双子查询非常昂贵。如果您在单个子查询中确定[hasPending]
并保存在某些JOIN
上,则效果可能会更好。
SELECT
[sub].[ID],
ROW_NUMBER() OVER (ORDER BY [sub].[hasPending] DESC, [sub].[ID] ASC) AS [RowID],
[sub].[hasPending]
FROM
(
SELECT
[Current].[ID],
(CASE WHEN COUNT([pending].[ID]) > 0 THEN 1 ELSE 0 END) AS [hasPending]
FROM [Current]
INNER JOIN [Current2]
ON [Current].[T2ID] = [Current2].[ID]
LEFT JOIN [Pending]
ON [Current].[ID] = [Pending].[ID] AND [Pending].[User] = 'Admin'
GROUP BY [Current].[ID]
) AS [sub]
修改:将COUNT(*)
更改为COUNT([pending].[ID])
,以便正确确定[hasPending]
。
答案 1 :(得分:1)
尝试一下,这应该加快速度,因为id会被转储到表变量而不必每次循环都要查询。这很可能不是最好的解决方案,但如果没有关于你要做什么的进一步信息,至少应该有所帮助。
declare @ids table
(
id int
)
insert into @ids(id)
SELECT [ID] From [Pending]
Inner Join [Current] On [Current].[ID] = [Pending].[ID]
WHERE ([Pending].[User] = 'admin')
SELECT ROW_NUMBER() OVER
(ORDER BY Case When [Current].[ID] In (select id from @ids)
THEN 1 ELSE 0 END ASC, [Current].[ID] ASC) As [RowID],
[Current].[ID],
Case When [Current].[ID] In (select id from @ids)
THEN 1 ELSE 0 END AS [HasPending]
FROM [Current]
INNER JOIN [Current2] AS [Table2] ON ([Current].[T2ID] = [Table2].[ID])
如果您的ID是唯一的,我也可以使用它,我认为它们是:
SELECT ROW_NUMBER() OVER
(ORDER BY a.haspending, a.[ID] ASC) As [RowID],
a.id, a.haspending,
from (select [Current].[ID],
Case when a.id is not null THEN 1 ELSE 0 END [HasPending]
FROM [Current]
INNER JOIN [Current2] AS [Table2] ON ([Current].[T2ID] = [Table2].[ID])
left join (SELECT distinct [ID] From [Pending]
Inner Join [Current] On [Current].[ID] = [Pending].[ID]
WHERE ([Pending].[User] = 'admin')) a on a.id = [Current].[ID]) a
答案 2 :(得分:0)
好吧,在Jacco建议的帮助下,修改它以给出正确的结果,我能够让它运行起来,将查询减少到令人惊讶的1秒...
WITH [ResultPage] AS
(SELECT
sub.id as id,
ROW_NUMBER() OVER (ORDER BY [sub].[hasPending] DESC, [sub].[ID] ASC) AS [RowID],
[sub].[hasPending]
FROM
(
SELECT
a.[ID],
(CASE WHEN p.[CID] is not null THEN 1 ELSE 0 END) AS [hasPending]
FROM [Alarm] a
full outer JOIN [Pending] as p
ON a.[ID] like p.[CID]
GROUP BY a.[ID],p.[CID]
) AS [sub]
INNER JOIN [Current2] ON (sub.[T2ID] = [Current2].[ID]))
SELECT [ResultPage].[RowID], [ResultPage].[HasPending], [Current2].[ID] As [Current2^ID],
etc...etc...
FROM [ResultPage]
INNER JOIN [Current] ON ([Current].[ID] = [ResultPage].[ID])
INNER JOIN [Current2] ON ([Current].[T2ID] = [Current2].[ID])
WHERE (([ResultPage].[RowID] BETWEEN -1 AND 50)) ORDER BY [ResultPage].[RowID] ASC