zoukankan      html  css  js  c++  java
  • U9在SQL Server上的性能优化经验(转述) — 之 使用long型的特定构造主键

    此文根据用友的文档《基于SQL Server 2008构建SOA大型管理软件技术实践》“翻译”而成,非原创。在baidu上看见此文,觉得写的很好,就将原先的PPT细化一下并除去废话。

    第一篇讲的是主键的选择。

     我就不废话int32和guid主键的优缺点了,这是他的PPT说明。

     

    用友采用的是long作为主键,这是原始PPT上的话:

     

    为实现不同站点间能够互相交换数据,必须保证站点间主键不串号,所以在最前端用两位是站点编号,理论上是100个, 这个问题应该不大,但是我在想,两个站点如果是集团内部可以协商使用不同的编号,如果是两个集团之间呢?思考中,有点挑刺了。

    不知道你注意到没有,他的年是位,这样就可以节省一位,当然,我觉得可以再改进,将日期转化为数字更好,可以参考 datetime的Second实现:

    public int Second
    {
        
    get
        {
            
    return (int) ((this.InternalTicks / 0x989680L% 60L);
        }
    }

     这个是精确到秒的,可以想办法删除到日期。

    为什么要在第二个部分放上日期呢?我猜想是希望数据被存储后,能够按照顺序存放,而不至于像GUID那样作为聚集索引后,数据插入时经常挪动位置(SQL Server新提供的创建GUID已经解决这个问题)。但是我觉得加入日期还是有问题的,这要看后面的顺序号。

    最后一部分是顺序号,根据PPT说明,应该是采用存储过程获取序号,但是我在想,某个日期在申请一个序号后,必须记录已经用到哪个序号,而且是区分不同日期。(缓存也一样),这样就必须为每个日期建立独立的行保存序列号,如果整个数据库公用一个序列,我想一年也就365条记录无所谓,但是如果每个表独立序列,就是4000*365条记录(U9 大约4000张表),那对于性能要求高的序列运算,似乎不妥。

    我的观点: 

    我觉得U9的主键设计是很不错的设计。当然,我们可以站在巨人的肩膀上继续改进。 

    我觉得他在规划段时,U9使用了十进制的概念,应该使用十六进制更好,有利于充分利用资源;

    应删除日期的部分,而改成后面全部是序号,这样就只用为每个表维护一个序列计数器了。 

    我的实践

    在我参与设计的ERP中,为提高主键的性能,采用了以下措施:

    1、使用int32的序列,一个表对应一个独立的序列,减少序列表的行数量。当然,没有考虑多站点的情况;

    2、获取序列的API被设计成批量获取,例如:IEnumerable<int> GetSeq(int count),例如在保存某个单据时,你(Application)很清楚需要多少个新的序列值,这样可以批量而减少往返;

    3、使用独立的应用程序服务处理序列,并采用类似买发票的原理来处理缓存、脱机应用,原理是:应用服务器获取一段(1000个)序列,并迅速保存结果到数据库,当客户端不断申请序列时,应用服务器并不需要写入数据而是直接在内存中扣减,如果出现断电,那么仅仅浪费一段编号而已。通过此方法解决了性能(使用缓存)、负载均衡(使用单一序列服务器)和脱机应用(联机时购买发票号)。此方案实际上是Oracle序列功能的改进版,因为SQL Server一直没有提供此功能搞的我很郁闷。

  • 相关阅读:
    Photoshop 基础七 位图 矢量图 栅格化
    Photoshop 基础六 图层
    Warfare And Logistics UVALive
    Walk Through the Forest UVA
    Airport Express UVA
    Guess UVALive
    Play on Words UVA
    The Necklace UVA
    Food Delivery ZOJ
    Brackets Sequence POJ
  • 原文地址:https://www.cnblogs.com/tansm/p/1832987.html
Copyright © 2011-2022 走看看