我想知道。我有一个复杂的查询,它在SQL Server2005Express版中运行大约3秒。
主表大约有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中复制了一个更好的可读性(仍然是tonz of logic:):
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 (datetime列,我刚刚添加了一个额外的索引),它需要我前面提到的时间。
我还试图“作弊”,并将我的语句作为子SELECT语句,以迫使他首先检索记录,然后在另一条SQL语句中执行ROW_NUMBER(),得到相同的性能结果。
发布于 2013-01-17 19:23:18
更新
在我仍然对解决方法感到沮丧之后,我进行了更多的调查。我删除了所有现有的索引,并对这些表运行了几个SQL语句。事实证明,使用新的sortorder的列和包含不同列的索引构建新索引解决了我的问题,并且使用dtedit (datetime)列的查询速度也很快。
所以学到的教训是:更多地注意你的索引和执行计划,并在你生产的软件的每次更新(新版本)时重新检查它们。
但是仍然想知道为什么CAST(datetime_column AS int)会让它变得更快...
https://stackoverflow.com/questions/14363616
复制相似问题