Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/meteor/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 行号()查询计划排序优化_Sql_Sql Server_Indexing_Sql Execution Plan - Fatal编程技术网

Sql 行号()查询计划排序优化

Sql 行号()查询计划排序优化,sql,sql-server,indexing,sql-execution-plan,Sql,Sql Server,Indexing,Sql Execution Plan,下面的查询访问包含3000多万行的投票表。然后使用选择结果集,其中n=1。在查询计划中,ROW_NUMBER()窗口函数中的排序操作占查询成本的95%,完成执行需要6分钟以上 我已经在相同选民、eid、国家/地区包括vid、nid、sid、投票、时间戳、新的上建立了一个索引,以涵盖where子句 更正此问题的最有效方法是在vid、nid、sid、new DESC、time_stamp DESC上添加索引,还是使用ROW_NUMBER()函数以更有效的方式获得相同的结果 SELECT v.vid,

下面的查询访问包含3000多万行的投票表。然后使用
选择结果集,其中n=1
。在查询计划中,ROW_NUMBER()窗口函数中的排序操作占查询成本的95%,完成执行需要6分钟以上

我已经在
相同选民、eid、国家/地区包括vid、nid、sid、投票、时间戳、新的
上建立了一个索引,以涵盖where子句

更正此问题的最有效方法是在
vid、nid、sid、new DESC、time_stamp DESC
上添加索引,还是使用ROW_NUMBER()函数以更有效的方式获得相同的结果

SELECT v.vid, v.nid, v.sid, v.vote, v.time_stamp, v.new, v.eid,
    ROW_NUMBER() OVER (
        PARTITION BY v.vid, v.nid, v.sid ORDER BY v.new DESC, v.time_stamp DESC) AS n
FROM dbo.Votes v
WHERE v.same_voter <> 1
    AND v.eid <= @EId
    AND v.eid > (@EId - 5)
    AND v.country = @Country
选择v.vid、v.nid、v.sid、v.vote、v.time\u stamp、v.new、v.eid、,
行号()结束(
按v.vid、v.nid、v.sid进行分区,按v.new DESC、v.time_stamp DESC)排序为n
来自dbo.v
其中v.same_投票人1
和v.eid(@eid-5)
和v.country=@country

使用
行编号()的一种可能的替代方法

选择
V.vid,
V.nid,
V.sid,
五、投票,
时间戳,
五、新,
开斋节
从…起
dbo.V.投票
左外联接dbo.V2打开
V2.vid=V.vid和
V2.nid=V.nid和
V2.sid=V.sid和
V2.1和
V2.eid(@eid-5)和
V2.country=@国家和地区
(V2.new>V.new或(V2.new=V.new和V2.time\u stamp>V.time\u stamp))
哪里
V.同一投票人1和
V.eid(@eid-5)和
V.country=@country和
V2.vid为空

查询基本上说是获取与您的条件匹配的所有行,然后连接到与相同条件匹配的任何其他行,但是根据
new
time\u stamp
列,这些行在分区中的排名更高。如果未找到,则该行必须是您想要的行(排名最高),如果未找到,则表示
V2.vid
将为
NULL
。我假设
vid
否则永远不能为
NULL
。如果它是表中的
NULL
able列,则需要调整查询的最后一行。

95%对于操作来说并不重要,您必须查看整个查询。它真的很慢吗?我唯一看到的是参数嗅探问题,因为您有2个参数。索引很好。我在问题中说,它需要6分钟以上的时间才能完成。此外,您所指的“良好”索引与行数()排序如此昂贵的问题/问题无关。索引是不好的,因为它从过滤的
1
相同的投票者开始(除非大多数值为“1”且您的索引已过滤)。在您的情况下,我建议将索引起始列更改为最有选择性。建立完整的数字表(行号)以精确地获取第一个/最后一个数字并不是最好的主意。您不允许sql server使用任何索引,只需选择min/max/top1即可。服务器的任务是枚举所有行,然后。。。好的,我将采用第一种模式。如果外部查询被严重过滤,则可以使用另一种模式来完成与行号相同的平局打破规则。你只想为一小部分选民找到最新的选票吗?如果是这样,我可以写一个答案。
不存在(选择,!=)
外部应用(前1个/min/max)
允许服务器优化和使用
半连接
,同时它将是一个相关子查询,也可以使用另一个索引(如果有)<代码>行号
不是免费的。每一个例子都是有史以来最糟糕的例子,其中一个人演示了如何为整个源代码构建数字,然后过滤掉一行。在1-10K行的
沙盒
表上,您不会感觉到它。你以后会感觉到的<代码>行号
对服务器来说意味着您没有在搜索-您正在动态构建一个新列。谢谢,我会检查这个。你是对的,
vid
不能为空。我最后做了类似的事情。再次感谢。
SELECT
    V.vid,
    V.nid,
    V.sid,
    V.vote,
    V.time_stamp,
    V.new,
    V.eid
FROM
    dbo.Votes V
LEFT OUTER JOIN dbo.Votes V2 ON
    V2.vid = V.vid AND
    V2.nid = V.nid AND
    V2.sid = V.sid AND
    V2.same_voter <> 1 AND
    V2.eid <= @EId AND
    V2.eid > (@EId - 5) AND
    V2.country = @Country AND
    (V2.new > V.new OR (V2.new = V.new AND V2.time_stamp > V.time_stamp))
WHERE
    V.same_voter <> 1 AND
    V.eid <= @EId AND
    V.eid > (@EId - 5) AND
    V.country = @Country AND
    V2.vid IS NULL