ROW_NUMBER OVER(ORDER BY date_column)

Yve*_*esR 6 sql-server performance sql-server-2005-express

我想知道.我有一个复杂的查询,它在大约3秒内在SQL Server 2005 Express版本中运行.

主表有大约300k行.

当我添加

ROW_NUMBER() OVER (ORDER BY date_column)
Run Code Online (Sandbox Code Playgroud)

date_column是一个datetime列需要123秒.

如果我做

ROW_NUMBER() OVER (ORDER BY string_title)
Run Code Online (Sandbox Code Playgroud)

它再次在3秒内运行.

我在datetime列上添加了一个索引.没变.还有123秒.

然后我尝试了:

ROW_NUMBER() OVER (ORDER BY CAST(date_column AS int))
Run Code Online (Sandbox Code Playgroud)

并且查询再次在3秒内运行.

由于转换需要时间,为什么SQL Server的行为如下?

更新:似乎ROW_NUMBER完全忽略我的WHERE语句并为所有可用条目构建行列列表?任何人都可以证实吗?

在这里,我在SQL Management Studio中复制了一个更好的可读(仍然是逻辑:)):

SELECT ROW_NUMBER() OVER (ORDER BY xinfobase.lid) AS row_num, *
FROM xinfobase
LEFT OUTER JOIN [xinfobasetree] ON [xinfobasetree].[lid] = [xinfobase].[xlngfolder] 
LEFT OUTER JOIN [xapptqadr] ON [xapptqadr].[lid] = [xinfobase].[xlngcontact] 
LEFT OUTER JOIN [xinfobasepvaluesdyn] ON [xinfobasepvaluesdyn].[lparentid] = [xinfobase].[lid] 
WHERE (xinfobase.xlngisdeleted=2 
AND xinfobase.xlinvalid=2) 
AND (xinfobase.xlngcurrent=1) 
AND ( (xinfobase.lownerid = 1  
       OR (SELECT COUNT(lid) 
           FROM xinfobaseacl 
           WHERE xinfobaseacl.lparentid = xinfobase.lid 
             AND xlactor IN(1,-3,-4,-230,-243,-254,-255,-256,-257,-268,-589,-5,-6,-7,-8,-675,-676,-677,-9,-10,-864,-661,-671,-913))>0 
               OR xinfobasetree.xlresponsible = 1) 
AND (xinfobase.lid IN (SELECT lparentid 
                       FROM xinfobasealt a, xinfobasetree t 
                       WHERE a.xlfolder IN(1369) 
                         AND a.xlfolder = t.lid 
                         AND dbo.sf_MatchRights(1, t.xtxtrights,'|')=1 )) ) 
AND ((SELECT COUNT(*) FROM dbo.fn_Split(cf_17,',') 
      WHERE [value] = 39)>0)
Run Code Online (Sandbox Code Playgroud)

这个查询在300k记录上需要2-3秒.现在我改变了ORDER BYxinfobase.xstrtitle在大约2-3秒,然后再次运行.如果我切换到xinfobase.dtedit(datetime列,我刚刚添加了一个附加索引),它需要上面提到的时间.

我还试图"欺骗"并将我的声明作为SUB SELECT强制他首先检索记录并ROW_NUMBER()在另一个SQL语句中执行外部操作,同样的性能结果.

Yve*_*esR 1

更新

在我仍然对解决方法感到沮丧之后,我进行了更多调查。我删除了所有现有索引并对表运行了多个 SQL 语句。事实证明,使用新的列排序顺序构建新索引并包含不同的列我解决了我的问题,并且使用 dtedit (日期时间)列进行查询也很快。

因此,吸取的教训是:更加关心您的索引和执行计划,并在您生成的软件的每次更新(新版本)时重新检查它们......

但仍然想知道为什么 CAST(datetime_column AS int) 之前使它变得更快......