慢速SQL命令

时间:2010-04-14 15:53:01

标签: sql sql-server

我需要从一个表中获取一些数据(并在路上展开一些XML)并将其放在另一个表中。由于源表可能有数千个或记录导致超时,因此我决定批量处理100条记录。代码按计划运行,因此批量处理可以为客户提供服务。如果我在源数据库中说200条记录,则sproc运行速度非常快,但如果有数千条记录需要几分钟。我猜测“TOP 100”在经过所有记录后才进入前100名。我需要在某些时候更改整个代码和sproc,因为它不能扩展但是现在有一个快速的解决方法可以让它更快地运行吗?

INSERT INTO [deviceManager].[TransactionLogStores] 
SELECT TOP 100 [EventId],
    [message].value('(/interface/mac)[1]', 'nvarchar(100)') AS mac,
    [message].value('(/interface/device) [1]', 'nvarchar(100)') AS device_type,
    [message].value('(/interface/id) [1]', 'nvarchar(100)') AS device_id,
    [message].value('substring(string((/interface/id)[1]), 1, 6)', 'nvarchar(100)') AS store_id,
    [message].value('(/interface/terminal/unit)[1]', 'nvarchar(100)') AS unit,
    [message].value('(/interface/terminal/trans/event)[1]', 'nvarchar(100)') AS event_id,
    [message].value('(/interface/terminal/trans/data)[1]', 'nvarchar(100)') AS event_data,
    [message].value('substring(string((/interface/terminal/trans/data)[1]), 9, 11)', 'nvarchar(100)') AS badge,
    [message].value('(/interface/terminal/trans/time)[1]', 'nvarchar(100)') AS terminal_time,
    MessageRecievedAt_UTC AS db_time
FROM [deviceManager].[TransactionLog]
WHERE EventId > @EventId
--WHERE MessageRecievedAt_UTC > @StartTime AND MessageRecievedAt_UTC < @EndTime
ORDER BY terminal_time DESC 

3 个答案:

答案 0 :(得分:1)

你需要ORDER BY吗?如果数据没有排序,TOP不需要将整个结果集恢复到前100。如果您确实需要订单,请确保您在terminal_time上有索引;如果花了这么长时间,你可能没有。

另外,请确保您在EventID上有索引。

答案 1 :(得分:0)

您有EventId(和MessageRecievedAt_UTC)的索引吗?

@EventId@StartTime/@EndTime的数据类型是否与相应的列相同?

答案 2 :(得分:0)

看起来像(如果我错了,请纠正我,这是其他一些构造)message.value()是一个总是采用相同输入的UDF。你每N行调用一次这个函数大约10次 - 这肯定是一个性能负担。如果这是一个确定性函数(我希望它是),你可以将这些各种函数调用的结果缓存到临时表中,性能应该会显着提高。

如果做不到这一点,可能是排序花费的时间最长。它必须先得到完整的结果集才能决定如何排序。正如马特指出的那样,一个指数可以大大加快这一速度。