SQL - 3.77亿表的性能差查询

时间:2016-05-17 08:58:49

标签: sql sql-server performance bigdata

我得到了一个具有以下结构的表:

Id | clientid | type | timeStamp | message |

我正在使用此查询来获取表的第一行以开始删除行但是崩溃了数据库:

SELECT TOP 10 [id]
      ,[clientid]
      ,[type]
      ,[timeStamp]
      ,[message]
FROM [db].[dbo].[table]
WHERE timeStamp LIKE '%2014-01-01 00:00:00.000%'

有没有办法在没有崩溃的情况下获取第一行并在到达timeStamp '2016-01-01 00:00:00.000'之前将其删除?

7 个答案:

答案 0 :(得分:3)

我不确定我是否理解这一点:

如果在TimeStamp列上设置索引,则应该绝对快速地过滤给定日期的行或多或少。

这些行将删除TimeStamp小于2016-01-01的表格中的所有内容。只剩下当前条目......

注意:小心!不要测试真实数据! : - )

DELETE FROM myTable
WHERE ID IN(SELECT ID 
            FROM myTable AS innerTbl 
            WHERE innerTbl.Timestamp<{ts'2016-01-01 00:00:00'}
           )

更新

这将删除每次调用1000行。 “GO”背后的数字将执行此片段377000次。用较小的数字进行测试......

BEGIN TRANSACTION;
DELETE FROM myTable
WHERE ID IN(SELECT TOP 1000
            ID 
            FROM myTable AS innerTbl 
            WHERE innerTbl.Timestamp<{ts'2016-01-01 00:00:00'}
           );
COMMIT;
GO 377000

答案 1 :(得分:1)

简单?

WHERE timeStamp = '2014-01-01 00:00:00.000'

答案 2 :(得分:1)

您为什么使用LIKE?这最有效地减慢了您的查询速度,LIKE通常用于比较部分字符串。

您可以截断日期时间,并使用正常比较:

SELECT TOP 10 [id]
      ,[clientid]
      ,[type]
      ,[timeStamp]
      ,[message]
FROM [db].[dbo].[table]
WHERE cast(timeStamp AS DATE) = '2014-01-01'

答案 3 :(得分:0)

如果没有额外的内容可以添加到日期时间,请不确定为何使用LIKE

使用=

SELECT TOP 10 [id]
      ,[clientid]
      ,[type]
      ,[timeStamp]
      ,[message]
FROM [db].[dbo].[table]
WHERE timeStamp ='2014-01-01 00:00:00.000'

或者,如果您尝试从当天开始全部使用CONVERT功能。 (我选择103,因为我看到你来自西班牙并使用DD/MM/YYYY格式。)

SELECT TOP 10 [id]
      ,[clientid]
      ,[type]
      ,[timeStamp]
      ,[message]
FROM [db].[dbo].[table]
WHERE CONVERT(VARCHAR(11),timeStamp ,103) = '01/01/2014'

答案 4 :(得分:0)

我猜ID是一个标识列?可能懒惰的DBA也把它作为聚集索引?只是做

DELETE TOP (10) from [Table] order by ID ASC

虽然在完全记录模式下会发出警告,这将是非常激烈的

答案 5 :(得分:0)

您应该在时间戳上创建一个索引。

你可以设置一个过滤的索引,因为它是一个相当大的表。

CREATE NONCLUSTERED INDEX IX_Table_timestamp ON Table([timestamp]) WHERE CONVERT(DATE,[timestamp]) = '2014-01-01';

然后按小批量删除行。

  

来自Aaron Bertrand的旧帖子中的代码。

SET NOCOUNT ON;

DECLARE @r INT;

SET @r = 1;

WHILE @r > 0
BEGIN
  BEGIN TRANSACTION;

  DELETE TOP (10000) 
    dbo.Table
    WHERE CONVERT(DATE,[timestamp]) = '2014-01-01';

  SET @r = @@ROWCOUNT;

  COMMIT TRANSACTION;

END

答案 6 :(得分:0)

如果您的自动增加列ID比使用ID选择第一行的原因?

DELETE TOP (1) from [Table] order by ID ASC