none
对于数据量很大,插入并发很高的表,大家对聚集索引的选择有何建议? RRS feed

  • 问题

  • 对于数据量很大,插入并发很高的表,大家对聚集索引的选择有何建议?

    如,考虑 pagelatch、索引维护等方面,用自增列、GUID、插入时间等

    2015年9月26日 1:13

答案

  • 不是很明白楼主要问什么

    1是问什么场景下使用聚集索引吗

    2使用聚集索引之后,应该使用什么技术来生成全局唯一ID,究竟使用是自增列,GUID,时间戳还是NEWSEQUENTIALID() 

    该使用哪种全局唯一ID技术来应对不同场景和性能问题

    比如pagelatch、索引维护

    第一个问题,数据量很大,插入并发很高的表,基本上表都需要加聚集索引

    第二个问题,不同的场景有不同的选择,简单的使用自增列,我们公司所有表都使用自增列,这样表分区会简单很多,维护也比较简单

    GUID,NEWSEQUENTIALID()基于全局的,比如同一个机器同一个库不同表,同一个机器不同库不同表,不同机器

    但是管理和维护比较麻烦,个人觉得

    时间戳跟自增id一样

    还有取模,可以解决last page latch问题,互联网公司基本都使用这种方式

    文章地址:http://www.cnblogs.com/shanksgao/p/3893873.html

    取模的弊端是:数据倾斜,不均匀

    反正没有同吃的方案,要结合公司实际情况,不同场景选择不同方案


    Love SQL


    2015年9月27日 15:54
  •  
    Steven 桦仔 的方案应该可以解决pagelatch带来的性能问题,但是索引的维护视乎不太好,由于按照ID进行分区,那么每个分区的数据睡着时间的推移,始终在变化,那么整个表估计需要全部重建索引一次,而不能像按时间分区那样,几乎可以只维护当前分区,以前的分区由于数据几乎不变而无需进行索引维护

    这个无所谓,索引维护的开销不是很大,找个合适的时间窗口就行。

    不过关键是,你要知道为什么这样做,选择合适的方案。只有很热的数据,有pagelatch压力才需要这样分区。


    想不想时已是想,不如不想都不想。

    2015年9月29日 6:04
    版主

全部回复

  • Try with identity first, it has least maintenance cost than others.
    2015年9月26日 3:39
  • 批量插入推荐用sqlbulkcopy来插入数据,

    要比频繁的开关库单条插入效率要高很多


    2015年9月27日 5:10
  • 不是很明白楼主要问什么

    1是问什么场景下使用聚集索引吗

    2使用聚集索引之后,应该使用什么技术来生成全局唯一ID,究竟使用是自增列,GUID,时间戳还是NEWSEQUENTIALID() 

    该使用哪种全局唯一ID技术来应对不同场景和性能问题

    比如pagelatch、索引维护

    第一个问题,数据量很大,插入并发很高的表,基本上表都需要加聚集索引

    第二个问题,不同的场景有不同的选择,简单的使用自增列,我们公司所有表都使用自增列,这样表分区会简单很多,维护也比较简单

    GUID,NEWSEQUENTIALID()基于全局的,比如同一个机器同一个库不同表,同一个机器不同库不同表,不同机器

    但是管理和维护比较麻烦,个人觉得

    时间戳跟自增id一样

    还有取模,可以解决last page latch问题,互联网公司基本都使用这种方式

    文章地址:http://www.cnblogs.com/shanksgao/p/3893873.html

    取模的弊端是:数据倾斜,不均匀

    反正没有同吃的方案,要结合公司实际情况,不同场景选择不同方案


    Love SQL


    2015年9月27日 15:54
  • 桦仔总算靠谱一次了。

    想不想时已是想,不如不想都不想。

    2015年9月27日 16:26
    版主
  • 对于数据量很大的表,需要使用分区表,如:使用时间进行分区,这样有个优势:索引碎片整理之后的分区,以后几乎不需要再整理了;但是按照时间分区,那么同一时刻插入的数据几乎在同一个分区,那么高并发插入的时候,就容易遭遇pagelatch的闩锁等待。

    如果不按照时间进行分区,那么对于大型表,索引的维护将是一个问题,因为每个分区里面的数据可能都进行了变化,所以最后使得整个表而不是某个分区都要进行索引的维护。


    2015年9月28日 7:42
  • 1. 顺序 insert, 尽量确保插入顺序与聚集索引顺序一致

    2. 分区, 在同一时间上插入的数据,分布到不同的分区上,相当于并发写多个分区, 登录同时插入 1-10 的数据,如果只有一个分区,那么是一个串行操作,但如果是分布在 10 个分区,那么就是并行操作(简单的测试过自增列+按自增id % 10 做分区键的情况, 效率可以提升很多)

    3. 不管表是否分区,它始终是在一个数据库里面,也就是鸡蛋始终是在一个篮子里,所以能够分表的就尽是考虑分表,将数据分布到不同的服务器上,配合程序设计,这样不单单是性能可以得到保障,还可以很容易做到横向扩展,当然,这样对程序设计要求俯高

    2015年9月28日 8:18
  •  
    Steven 桦仔 的方案应该可以解决pagelatch带来的性能问题,但是索引的维护视乎不太好,由于按照ID进行分区,那么每个分区的数据睡着时间的推移,始终在变化,那么整个表估计需要全部重建索引一次,而不能像按时间分区那样,几乎可以只维护当前分区,以前的分区由于数据几乎不变而无需进行索引维护
    2015年9月29日 1:15
  • Partitioning is not really always good for big table, at lease unable to generate accurate stats.
    2015年9月29日 2:03
  •  
    Steven 桦仔 的方案应该可以解决pagelatch带来的性能问题,但是索引的维护视乎不太好,由于按照ID进行分区,那么每个分区的数据睡着时间的推移,始终在变化,那么整个表估计需要全部重建索引一次,而不能像按时间分区那样,几乎可以只维护当前分区,以前的分区由于数据几乎不变而无需进行索引维护

    这个无所谓,索引维护的开销不是很大,找个合适的时间窗口就行。

    不过关键是,你要知道为什么这样做,选择合适的方案。只有很热的数据,有pagelatch压力才需要这样分区。


    想不想时已是想,不如不想都不想。

    2015年9月29日 6:04
    版主
  • 需求、场景都不明确,太难去猜(或者说精准设计)

    通常不仅仅是并发写入,还可能考虑一些查询甚至分析,不仅仅是索引,还有其他整体性、综合的东西需要考量、权衡

    大是个抽象词,如果能量化一下会靠谱点,大家谈论也有个参考,比如每秒多少条记录,每天多少数据量等

    数据有什么特点,是否归档,是否热数据重点处理等


    Try SQL Server 2008 QQ:315054403 dgdba@hotmail.com

    2015年9月30日 9:19
  • 哈哈哈,最高时估计秒入3000条,每天7000万条左右,需要归档,每天数据量压缩了都有15GB左右!

    不考虑队列之类的,而且数据库为一台机器

    2015年10月10日 1:02
  • 哈哈哈,最高时估计秒入3000条,每天7000万条左右,需要归档,每天数据量压缩了都有15GB左右!

    不考虑队列之类的,而且数据库为一台机器

    这个数据量,identity是可以的。建议按时间分区就可以了。

    但是你这个需求场景还是很不明确的,你只提到了插入的数据量,没有提到了具体插入的顺序、方式,而且没有查询的情况。

    BTW,7千万压缩后15GB,你的表不是太宽,这是DW吗?


    想不想时已是想,不如不想都不想。

    2015年10月10日 6:21
    版主
  • 这是用户访问的日志信息,是拿来做一下分析之类的

    现在的确是按照时间分区的,只是前面用队列写了的,如果一条一条硬写数据库,也许会有pagelatch_ex的问题

    2015年10月10日 7:35
  • 每秒3K,每天7kW,,需要DBA动手

    DBA肯定不是仅仅会SIUD,或建表+备份的活


    Try SQL Server 2008 QQ:315054403 dgdba@hotmail.com

    2015年10月11日 10:59