MS SQL,单一语句VS复杂语句 谁快

  最近帮朋友搞一个电子黄页的基目,里面有几百万数据,其中一个表包含了以下几个字段:
  ID(主键,标识,自增长int,索引),

  CityID(城市ID,int,索引),

  CateID(类别ID,int,索引),

  CateParentID(父类别ID,int,索引)。


  类别只有2级,所以,为了加快查询效率,索性把大类ID和小类ID都单独列为字段。


  按照习惯,在查询某个大类ID时候,例如查询大类ID为112的第一页黄页数据时,用了常用的语句

  select top 10 * from E_Table where CateParentID=112


  虽然CateParentID做了索引,虽然只是查询10条数据,但是拥有近400万条记录的情况下,这个简单的查询居然用了45秒才得到结果。以致搜索引擎迟迟无法更新网页的快照。真是急煞我也。
  之后按照某高人指点:若无法从该索引筛选出低于总数据量1%的结果,则不应该添加索引,去除了CateParentID的索引。然而情况并没有好转,仍然维持在42秒左右。

  但是条件一旦换成是CateID=xxx的时候,速度总是出奇的快。CateParentID和CateID都是int型,且都有索引,区别怎么会这么大呢?在操作上,CateID列是在创建表的时候添加的,而CateParentID列是在数据全部进表后才添加的,难道仅仅是因为原生的和后加的数据列竟然会被MS区别对待?
  就数据量而言,400万的数据对于MS SQL来说应该算是小儿科了,有同事建议我采用“水平切割”,即按大类进行分表,但我认为区区几百万就采用分表分明是种逃避。

  于是我不甘心这么简洁的语句就这样死掉,换成这样

  select top 10 ID from E_Table where CateParentID=112 之后满怀期待地等了近40+秒...

  最后一丝希望破灭,于是赶紧另想办法,今天是礼拜三,百度刷新快照的好日子。我想到之前做随机取数据的时候,select ID from table取所有ID到内存,之后再随机N条,这个取的过程非常快,尽管数据量也非常大,“何不把CateParentID和ID先取来,再给条件,无视其它数据”我这样想着,于是有了下面的语句:
select * from [E_Table] where ID in (
   select top 10 [t0].[ID] from (
     select ID,CateParentID from [E_Table]
   ) as [t0] where [t0].[CateParentID]=112
)
这个运行倒是很快,在本地300毫秒内返回结果,但是要注意的是查询条件需要的列必须在第一次就全部取到(即最底层),另外要注意如果有全文索引,可以把全文索引的条件写在最外层,速度也是非常快!

结论:(1)窃以为,int型数据+索引在大数据量时对查询速度的帮助不大。
      (2)窃以为,单条简洁的SQL语句未必比嵌套的快。
      (3)窃以为,原生的列和在大量数据之后附加的列,在同等条件查询速度上,貌似是亲妈生的和后妈生的。纯属猜想,该结论尚未得到证实。希望有行家里手加以指正,小弟感激不尽。

      (4)窃以为,这个标题和内容还是有点不相符,但是我无法用精练的话概括我的内容.

posted @ 2012-05-14 11:43  活跃的毛虫  阅读(4514)  评论(65编辑  收藏  举报