技术开发 频道

浅谈SQL"简单的"SELECT TOP应注意细节

  从这个查询计划中大家可以清楚的看到

  第一种扫描完zhuisuo表后先降序(top N Sort)然后在4行范围中取前2行

  第二种扫描完zhuisuo表后先升序取4行(top N Sort)然后再把这4行降序取2行(top N Sort)

  在这里就不得不简单的说说SQL语句中出现的表子查询了

  表子查询,而出现在from子句中的表我们称为派生表

  派生表是虚拟的,未被物理具体化,也就是说当编译的时候

  如(select top 2 * from (select top 4 * from zhuisuo) m order by m.id desc )

  外部查询和内部查询会被合并,并生成一个计划

  这时再看看上面的执行计划就一目了然了

  (注意事项:在派生表里面一般不允许使用order by除非指定了top

  也就是说select top 2 * from (select * from zhuisuo order by id asc) m order by m.id desc这句语句是不能执行的)

  接下来我再举例关于top需要注意的细节

  1、使用top返回随机行,很多人会想到用RAND函数从而得到这样一个语句

  select top 4 id,name from zhuisuo order by rand();

  经过多次查询后,你会失望的发现它没有返回随机行

  这是因为每个查询只调用它一次而不是每行调用它一次

1
 

  这时我们可以把RAND改为Newid

  select top 4 id,name from zhuisuo order by newid();

  这时就会得到你想要的结果了,在这里我们可以意识到NEWID具有更好的分布特性

1
 

  2、注意insert中使用top

  insert top (4) into zhuisuo

  select * from zhuisuo order by id desc

  很多网友会解释为把zhuisuo表中最后4条插入表

  但执行完毕后又会让你失望了,插入的是最前面的4条

  正确的倒叙插入top方法应该是

  insert into zhuisuo

  select top (4) * from zhuisuo order by id desc

  这两条语句又有什么区别

1
 

  其实第上面那条语句更本就没有排序(Top N Sort)  

0
相关文章