English 中文(简体)
以 - 日期、时间和字符串比较 - 非常慢删除
原标题:Delete with WHERE - date, time and string comparison - very slow

我有一个慢动作的查询 并且希望一个在 Sql 知识稍多一点的人 能够帮助我 改善业绩:

我有两个表格 一个源代码和一个常见数据, 我加载一些包含日期、 时间和字符串( whch is a server name) 和一些数据 。

来源表格中可包含40k+行(有30个单列,混合了英寸、日期、时间和一些vachars(255)/(Max))

我用下面的查询从共同数据中删除源头中的任何数据:

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
  • Date varchar(255) I.E 2012-05-22
  • Time varchar(255) I.E 08:12:21

共同领域采用这种格式:

  • ServerName varchar(255) I.E SN1234
  • Date date I.E 2011-08-10
  • Time time(7) I.E 14:25:34.0000000

谢谢 谢谢

最佳回答

将两边转换为字符串, 然后将其转换成一个大字符串, 然后比较这些结果效率不高。 只在您需要的地方进行转换。 试一下这个例子, 看看它是如何比较的 :

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;
问题回答

所有转换为 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
);

类似

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

如果之后太慢,那么你需要一些指数,在两个表格上都可能。

删除不必要转换将会帮助很多, 正如 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);

这将为您提供一个索引日期时间栏,用以寻求并大大改进您的执行计划,而以某些插入性能为代价。





相关问题
SQL SubQuery getting particular column

I noticed that there were some threads with similar questions, and I did look through them but did not really get a convincing answer. Here s my question: The subquery below returns a Table with 3 ...

难以执行 REGEXP_SUBSTR

I m 查询Oracle 10g。 我有两张表格(样本数据见下文)。 i m 试图提取一些领域

SQL Query Shortcuts

What are some cool SQL shorthands that you know of? For example, something I learned today is you can specify to group by an index: SELECT col1, col2 FROM table GROUP BY 2 This will group by col2

PHP array callback functions for cleaning output

I have an array of output from a database. I am wondering what the cleanest way to filter the values is example array Array ( [0] => Array ( [title] => title 1 ...

OracleParameter and DBNull.Value

we have a table in an Oracle Database which contains a column with the type Char(3 Byte). Now we use a parameterized sql to select some rows with a DBNull.Value and it doesn t work: OracleCommand ...

Running numbers in SQL

I have a SQL-statement like this: SELECT name FROM users WHERE deleted = 0; How can i create a result set with a running number in the first row? So the result would look like this: 1 Name_1 2 ...

How to get SQL queries for each user where env is production

I’m developing an application dedicated to generate statistical reports, I would like that user after saving their stat report they save sql queries too. To do that I wrote the following module: ...

热门标签