我在想。我有一个复杂的查询,它在大约3秒内在SQL Server 2005 Express版本中运行。
主表有大约300k行。
当我添加
ROW_NUMBER() OVER (ORDER BY date_column)
date_column
为datetime
列需要123秒。
如果我这样做
ROW_NUMBER() OVER (ORDER BY string_title)
它再次在3秒内运行。
我在datetime
列上添加了一个索引。没变。还是123秒。
然后我尝试了:
ROW_NUMBER() OVER (ORDER BY CAST(date_column AS int))
并且查询再次在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)
此查询在300k记录上需要2-3秒。
现在我将ORDER BY
更改为xinfobase.xstrtitle
,然后再次在2-3秒内运行。
如果我切换到xinfobase.dtedit
(带有我刚添加的附加索引的日期时间列),它需要上面提到的时间。
我还试图“作弊”并将我的声明作为SUB SELECT强制他首先检索记录,然后在另一个SQL语句中执行ROW_NUMBER()
,同样的性能结果。
答案 0 :(得分:0)
<强>更新强>
在我仍然对做一个变通方法感到沮丧之后,我正在调查更多。 我删除了所有现有索引,并针对表运行了几个SQL语句。 事实证明,使用新的排序列构建新索引并包含不同的列我修复了我的问题,查询也很快与dtedit(datetime)列。
经验教训: 更多地关注您的索引和执行计划,并在您生成的软件的每个更新(新版本)中重新检查它们......
但仍然想知道为什么CAST(datetime_column AS int)在...之前使它变得快速。