使用WHERE删除 - 日期,时间和字符串比较 - 非常慢

时间:2012-05-22 21:10:00

标签: sql sql-server performance sql-server-2008 tsql

我的查询速度很慢,希望有更多知识的人可以帮助我提高性能:

我有2个表一个Source和一个Common,我加载了一些数据,其中包含Date,Time和String(什么是服务器名称),加上一些..

Source表可以包含40k +行(它有30个奇数列,包含整数,日期,时间和一些varchars(255)/(Max)

我使用以下查询从源中删除Common中的所有数据:

'Delete from Common where convert(varchar(max),Date,102)+convert(varchar(max),Time,108)+[ServerName] in (Select convert(varchar(max),[date],102)+convert(varchar(max),time,108)+ServerName from Source where sc_status < 300)'

源字段采用以下格式:

  • ServerName varchar(255) I.E SN1234
  • 日期varchar(255) I.E 2012-05-22
  • 时间varchar(255) I.E 08:12:21

公共字段采用以下格式:

  • ServerName varchar(255) I.E SN1234
  • 日期 I.E 2011-08-10
  • 时间时间(7) I.E 14:25:34.0000000

由于

4 个答案:

答案 0 :(得分:5)

将两边转换为字符串,然后将它们连接成一个大字符串,然后比较这些结果效率不高。只进行必要的转换。试试这个例子,看看它是如何比较的:

DELETE c
  FROM dbo.Common AS c
  INNER JOIN dbo.Source AS s
  ON s.ServerName = c.ServerName
  AND CONVERT(DATE, s.[Date]) = c.[Date]
  AND CONVERT(TIME(7), s.[Time]) = c.[Time]
  WHERE s.sc_status < 300;

答案 1 :(得分:0)

所有这些转化为VARCHAR(MAX)都是不必要的,可能会减慢您的速度。我会从这样的事情开始:

DELETE c
from [Common] c
WHERE EXISTS(
    SELECT 1
    FROM Source
    WHERE CAST([Date] AS DATE)=c.[Date]
    AND CAST([Time] AS TIME(7))=c.[Time]
    AND [ServerName]=c.[ServerName]
    AND sc_status < 300
);

答案 2 :(得分:0)

这样的东西
Delete from Common inner join Source 
On Common.ServerName = Source.ServerName 
and Common.Date = Convert(Date,Source.Date)
and Common.Time = Convert(Time, Source.Time)
And Source.sc_Status < 300

如果之后太慢,那么你需要一些索引,这两个表都可以。

答案 3 :(得分:0)

删除不必要的转换将有助于Aaron的回答中详细说明。您还可以考虑在日志表的顶部创建索引视图,因为您可能在该模式中没有太多灵活性或从日志解析器插入DML。

简单示例:

create table dbo.[Source] (LogId int primary key, servername varchar(255), 
   [date] varchar(255), [time] varchar(255));
insert into dbo.[Source]
    values  (1, 'SN1234', '2012-05-22', '08:12:21'),
            (2, 'SN5678', '2012-05-23', '09:12:21')
go

create view dbo.vSource with schemabinding
as
    select  [LogId],
            [servername], 
            [date], 
            [time], 
            [actualDateTime] = convert(datetime, [date]+' '+[time], 120)
    from    dbo.[Source];
go

create unique clustered index UX_Source on vSource(LogId);
create nonclustered index IX_Source on vSource(actualDateTime);

这将为您提供一个索引日期时间列,可以在其上寻求并以一些插入性能为代价大大改进您的执行计划。