4

我的查询执行速度很慢,希望对 sql 有更多了解的人可以帮助我提高性能:

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

源表可以包含 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)'

源字段采用以下格式:

  • 服务器名称 varchar(255) IE SN1234
  • 日期 varchar(255) IE 2012-05-22
  • 时间 varchar(255) IE 08:12:21

公共字段采用以下格式:

  • 服务器名称 varchar(255) IE SN1234
  • 日期日期IE 2011-08-10
  • 时间时间(7) IE 14:25:34.0000000

谢谢

4

4 回答 4

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;
于 2012-05-22T21:30:36.850 回答
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
);
于 2012-05-22T21:21:44.943 回答
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);

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

于 2012-05-22T21:57:44.520 回答
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

如果在那之后它太慢了,那么你需要一些索引,可能在两个表上。

于 2012-05-22T21:36:31.127 回答