为什么80%的码农都做不了架构师?>>>   

有了前面的《动手》,基本上可以进行开发了。本篇我们来试试XCode的基本功功力如何,测试在单表一千万业务数据的环境下查询的速度,添删改等没什么可测试的。其实应该说是XCode开发模式的功力,XCode组件仅仅是处理分页而已,而XCode开发模式为高性能开发提供了更多的建议。

测试环境:双核CPU,4G内存,win7+SQL2008+vs2010

数据表字段包括:自增ID、车牌、时间。使用SQL准备一千万测试数据,花了将近一个小时。

测试用例:ID的升序降序,时间的升序降序,每一种情况测试取首页、中间页、尾页的时间。

XCode开发模式非常看重分页,基本上所有集合查询方法都带有分页参数。Entity层只负责生成获取满足条件的所有数据的SQL,加上分页参数后传递给下层数据访问层,自身不处理问题。数据访问层调用IDatabase接口的PageSplit方法,把上述的SQL处理为只获取指定页的SQL,然后再执行查询操作。因为不同的数据库分页方法不同,所以XCode的这种架构让使用者无需关心采用哪一种分页方法。测试环境是SQL2008,所以自动采用row_number分页。

首先建立数据表

代码

CREATE   TABLE   [ dbo ] . [ test ] (
     [ ID ]   [ int ]   IDENTITY ( 1 , 1 )  NOT   NULL ,
     [ HPHM ]   [ varchar ] ( 50 )  NULL ,
     [ JGSJ ]   [ datetime ]   NOT   NULL ,
  CONSTRAINT   [ PK_CLTXJL ]   PRIMARY   KEY   CLUSTERED  
(
     [ ID ]   DESC
) WITH  (PAD_INDEX   =   OFF , STATISTICS_NORECOMPUTE   =   OFF , IGNORE_DUP_KEY  =   OFF , ALLOW_ROW_LOCKS   =   ON , ALLOW_PAGE_LOCKS   =   ON )  ON   [ PRIMARY ]
)  ON   [ PRIMARY ]

使用SQL语句插入一千万行数据

declare   @i   int
set   @i = 0
while   @i < 100
begin
insert   into  test  values ( ' 鄂A94450 ' , getdate ())
insert   into  test  values ( ' 鄂A92355 ' , getdate ())
(这里是更多数据插入语句)
set   @i = @i + 1
end
GO

最后是这种样子

再看看我们准备的测试代码

测试代码

static   void  Test2()
{
    Stopwatch sw  =   new  Stopwatch();
    sw.Start();

Console.WriteLine();
    DAL.AddConnStr( " Center " ,  " Data Source=.;Initial Catalog=Center;User ID=sa;Password=Pass@word " ,  null ,  " sql2008 " );
    IEntityOperate factory  =  DAL.Create( " Center " ).CreateOperate( " test " );
    sw.Stop();
    Console.WriteLine( " 初始化:{0} " , sw.Elapsed);

ICollection list  =  factory.FindAll( null ,  null ,  null ,  100000 ,  1 );
    DateTime dt  =  DateTime.Now;
     foreach  (IEntity item  in  list)
    {
        dt  =  (DateTime)item[ " JGSJ " ];
         break ;
    }

// String where = String.Format("{0}>='{1}' And {0}<'{2}'", "JGSJ", dt, dt.AddSeconds(100));
    String  where   =  String.Empty;

sw.Reset();
    sw.Start();
    Console.WriteLine();
    Int32 count  =  factory.FindCount( where ,  null ,  null ,  0 ,  0 );
    sw.Stop();
    Console.WriteLine( " 查询总记录数:{0} " , sw.Elapsed);
    Console.WriteLine( " 总记录数:{0} " , count);

Test2_0(sw,  " 默认顺序 " , count,  where ,  null );
    Test2_0(sw,  " 时间升序 " , count,  where ,  " JGSJ Asc " );
    Test2_0(sw,  " 时间降序 " , count,  where ,  " JGSJ Desc " );
}

///  
///  测试用例
///  
///   计时器
///   标题
///   总记录数
///   条件字句
///   排序字句
static   void  Test2_0(Stopwatch sw, String title, Int32 count, String  where , String order)
{
    Console.WriteLine();
    Console.WriteLine( " {0}: " , title);

IEntityOperate factory  =  DAL.Create( " Center " ).CreateOperate( " test " );

sw.Reset();
    sw.Start();
    Console.WriteLine();
    ICollection list  =  factory.FindAll( where , order,  null ,  0 ,  10 );
    sw.Stop();
    Console.WriteLine( " 查询前10行:{0} " , sw.Elapsed);

sw.Reset();
    sw.Start();
    Console.WriteLine();
    list  =  factory.FindAll( where , order,  null , count  /   2 ,  10 );
    sw.Stop();
    Console.WriteLine( " 中间10行({1}):{0} " , sw.Elapsed, count  /   2 );

sw.Reset();
    sw.Start();
    Console.WriteLine();
    list  =  factory.FindAll( where , order,  null , count  -   10 ,  10 );
    sw.Stop();
    Console.WriteLine( " 最后10行({1}):{0} " , sw.Elapsed, count  -   10 );
}

上面第一个方法是控制方法,用来控制测试用例的。第二个方法就是测试用例了。

在这里不得不提的是,第一个方法使用了最新版本V5.0的新特性——弱类型访问。上一篇《动手》中提到,使用XCode首先需要利用代码生成器生成实体类代码,或者手工编写,反正是需要实体类代码,而本文只是为了测试,不需要那么复杂。动态添加一个连接字符串Center,并创建数据表test的操作接口,后面就可以利用这个操作接口去查询数据了。弱类型访问这一块后面会专门介绍。

第二个方法有三次查询,分别是首页、中间页和尾页。

先来看看“默认顺序”,其实就是ID降序

因为数据表默认为自增ID建立聚集索引,所以在ID字段上的分页查询是最快的,首页才3毫秒,中间页也才4.5秒。

这里有必要说一下尾页,这里不是作弊,而是XCode的一个小手段。在实际应用分页查询的时候,往往是越往后越慢,但只要把数据倒过来查,ID降序的尾页其实就是ID升序的首页,结果行集一致,只不过这10行数据是倒过来的,XCode在最后返回实体集合的时候会把它倒过来,就成了ID降序了。所以,在XCode查询中,中间页以后的页都是反向查询,中间页是最慢的。

接着看看“时间升序”

首页和尾页5秒,中间页17秒,很糟糕!看一下它们的执行计划


习惯性的先看总开销,三条语句居然是平分秋色,执行时间一致!这个我就无法解释了。

从执行计划可以看到,95%的开销都在于排序

看详情,原来是对JGSJ的排序造成的。看来应该为JGSJ建立索引。

最后的这个“时间降序”,时间跟“时间升序”差不多,原理也一样,就不分析了。

上次第一轮测试看到,没有索引,实在杯具!下面我们给JGSJ字段加上索引,继续测试

有了明显变化,首页和尾页足够快了,中间页也变快了,但是还是偏慢,怎么回事?从执行计划看到,99%的时间都在于键查找

原来是查找对应的HPHM,也是,索引只负责时间字段,而HPHM字段还是需要做全表扫描找出来的。在索引里面包含它试试

CREATE   NONCLUSTERED   INDEX  IX_test_1  ON  dbo.test
(
  JGSJ
)
include (HPHM)
WITH ( STATISTICS_NORECOMPUTE  =   OFF , IGNORE_DUP_KEY  =   OFF , ALLOW_ROW_LOCKS  =   ON , ALLOW_PAGE_LOCKS  =   ON )  ON   [ PRIMARY ]

再次测试

漂亮!结果跟ID自增字段一样。

综合上面的测试,最慢的中间页能保持在5秒以内,算是一个不错的成绩了。不过这不能完全算是XCode的功劳,XCode仅仅是生成了分页语句而已。而建立索引的建议,则是XCode开发模式的范畴。

XCode开发模式建议:每个表使用自增ID作为主键,独享聚集索引。在数据分页上,没有比自增ID加上聚集索引更快的了,所以要把最好的留给它。业务主键还有经常查询的字段,根据情况建立非聚集索引。在千万数据下,没有索引的字段,基本上查不动。

建立索引时,特别注意包含字段include(不是组合索引)。比如为时间字段建立了索引,根据时间字段查询的时候,扫描索引字段会很快,但是扫描之后绝大部分时间都花在查找时间字段对应的车牌字段上了,如果建立时间字段索引的时候,把车牌字段include进去,就相当于在索引目录里面就拥有了车牌信息,直接省去了对应车牌这一步,查询性能将会得到非常大的提高。当然,include也是有代价的,添删改操作会比原来慢,并且要占用更大的存储空间。不过现在硬盘那么便宜,存储空间问题不会太大,至于添删改操作慢多少,就看业务来衡量了,一般可以接受。

在SQLServer管理工具里面建立索引时,似乎无法添加include字段。可以先设置好索引,不要保存,点击生成脚本,然后复制到查询窗口,增加include后再执行。

前面的测试,都是简单的没有查询条件的测试,下面我们试试带查询条件的测试

屏幕一闪而过,就这样完了!图中看到,符合条件的数据共有2317+10=2327条,在这么小的数据量里进行分页查询,那速度,自然没得说!

在实际应用中,很少有需要查询那么多页的,百度、谷歌和淘宝等大型网站,最多也就返回前面一百页。并且,业务系统一般有很多查询条件,比如时间段等,经过这些条件过滤,即使是千万数据的表,也不会有太多满足条件的数据

这一切,XCode已经为你准备!

大石头

新生命开发团队

2010-09-07 03:57

组件文档打包下载(1~6)

作者: 大石头 发表于 2010-09-15 23:28 原文链接

评论: 23 查看评论 发表评论

最新新闻:
· 是否该让开发人员跟客户直接交流?(2010-12-21 07:53)
· 亚马逊副总裁跳槽Groupon任CFO(2010-12-21 07:50)
· Gmail语音服务将延长至2011年底(2010-12-21 07:49)
· AOL收购个人档案网站About.me(2010-12-21 07:48)
· AT&T 19.25亿美元购入高通 700MHz 低频频谱(2010-12-21 07:42)

编辑推荐:Mono又更新了

网站导航:博客园首页  我的园子  新闻  闪存  小组  博问  知识库

转载于:https://my.oschina.net/nnhy/blog/11368

6,ORM组件XCode(撬动千万级数据)相关推荐

  1. 充血模型的ORM能做什么?——ORM组件XCode(十八般武艺)

    ORM组件XCode(十八般武艺)<?xml:namespace prefix = o /> 之前,XCode总是若隐若现,耐性好的同学想知道它还有啥特点,沉不住气的则认为不过是CURD耳 ...

  2. ORM组件XCode(十八般武艺)

    之前,XCode总是若隐若现,耐性好的同学想知道它还有啥特点,沉不住气的则认为不过是CURD耳! XCode开发模式是灵魂,XCode组件通过具体实现对其支持! XCode的特点如下: 0.基本的CU ...

  3. 3,ORM组件XCode(简介)

    为什么80%的码农都做不了架构师?>>>    XCode是一个轻量级的ORM组件(对象与关系数据库映射),提供以面向对象的方式操作数据库的功能,能够解决90%以上的数据库操作场景. ...

  4. 5,ORM组件XCode(动手)

    本篇才真正是XCode教程第一篇.<速览>是为了以最简洁的语言最短小的篇幅去吸引开发者:<简介>则是对XCode组件和XCode开发模式的一个整体介绍,让开发者从宏观的角度去理 ...

  5. 京东11·11:撬动数据中心的支点——京东阿基米德

    今年11.11,京东数据中心操作系统(JDOS)阿基米德已经全面接管了应用资源调度.每日调度百万台容器实例运转,每日为离线计算提供了多达3000万核·小时的计算资源,SLA履约率达到98.3%.在保证 ...

  6. 扇贝编程python是干嘛的-产品观察 | 以对话式互动学习撬动转化,扇贝编程瞄准职教市场...

    原标题:产品观察 | 以对话式互动学习撬动转化,扇贝编程瞄准职教市场 成人编程教育是职业教育行业最火热的赛道之一,除了行业内的垂直创业公司,越来越多教育公司也在把业务线延展至这一领域,以便深度结合业务 ...

  7. 18篇文章系统解读:中台规划如何撬动企业IT基础设施转型升级

    摘要:通过这个系列,让大家对中台的价值.针对的问题痛点.中台规划的方法思路和技巧.一些中台业务实践有个基本的认识,让客户清楚的意识到企业中台的业务价值,进而通过企业中台规划牵引客户IT基础设施投资. ...

  8. 蚂蚁金服上市,还想撬动杭州和北京房价?

    最近看到好多人,都在说蚂蚁金服要上市了,一批程序员要财富自由了,杭州和北京房价是不是要涨了? 小朋友你的小问号很天真呀,今天咱们就一起来梳理一下,看看能否撬动房价. No1 你这个问题,我不知道如何回 ...

  9. 希望流程挖掘成为撬动企服市场的突破口 | 专访凡得科技CEO海广跃、首席技术顾问刘聪

    2022年,全球流程挖掘市场规模预计将达70多亿人民币,而目前中国流程挖掘行业尚处于市场启蒙期,仅少数大型企业与机构对流程挖掘进行了初步或尝试性的投入.从目前来看,原生流程挖掘厂商会直接面向客户输出流 ...

最新文章

  1. 修改 Android 5.1 默认设置
  2. 软件驱动安装在docker_别为Docker本地实现不支持GPU发愁,解决方案在此!
  3. 【机器学习】——纯Python建立BP模型
  4. Android之提示Invalid Region.Op - only INTERSECT and DIFFERENCE are allowed
  5. 海量数据寻找最频繁的数据_寻找数据科学家的“原因”
  6. 打造大数据和AI能力底座 联通大数据深度参与“新基建”
  7. Uber Go语言编码规范
  8. java笔试必考知识_面试必备:常考Java基础知识总结(持续更新)
  9. MySQL 大表优化方案(长文)
  10. tcpdump抓SQL[转]
  11. 记录一次腾讯面试经历
  12. 合规安全大考核:移动应用安全策略全盘点
  13. 第三方登录mysql表_浅谈数据库用户表结构设计,第三方登录
  14. 硬纪元干货|爱奇艺吴霜:看好互动视频、AI陪伴以及VR直播
  15. 图像视频滤镜算法---颜色滤镜
  16. 关于极光推送报错6003的一些问题
  17. 微生物组-宏基因组分析(线上/线下同时开课,2021.11)
  18. 为什么少女怀孕越来越普遍
  19. 各种台式计算机计量单位相同吗,计算机常见计量单位解析
  20. windows 控制linux,windows远程控制linux的最佳方案

热门文章

  1. onedrive目录PHP源码,另一个OneDrive目录索引应用 OLAINDEX
  2. 苏格拉底的oracle,苏格拉底的五个经典故事
  3. Hadoop详解(九):Hadoop Streaming和Pipes原理和实现
  4. anaconda tensorflow 2.3_安装anaconda amp;源码安装lightgbm,xgboost
  5. python正则匹配ip地址_Python正则表达式匹配ip地址实例
  6. Choose unique values for the 'webAppRootKey' context-param in your web.xml files!
  7. manven需要注意点几点
  8. 2018年各大互联网前端面试题三(阿里)
  9. 在IIS上搭建WebSocket服务器(三)
  10. Bootstrap 与 Jquery validate 结合使用——简单实现