首页 新闻 论坛 群组 Blog 文档 下载 读书 Tag 网摘 搜索 .NET Java 游戏 视频 人才 外包 培训 数据库 书店 程序员
中国软件网
欢迎您:游客 | 登录 注册 帮助
  • 事情紧急,期待大家和邹兄的解答!非常频繁且大数据量的向表中写数据,导致有索引的表的索引碎片增长很快。。。。 [已结贴,结贴人:scmyxj]
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • scmyxj
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    • 揭帖率:
    发表于:2008-02-22 22:14:37 楼主
    现在有一系统,数据库中的其中几个表会被很频繁地INSERT,有几个表会被很频繁地UPDATE和INSERT,
    这些表的数据量非常大(INSERT的表每秒有几千条记录,UPDATE和INSERT的表每秒的记录稍小一点),
    我现在采用的办法是,做INSERT的表没有建索引,是按天分区且只保留最近15天的记录,做UPDATE和INSERT的表建有索引(个数为1-4个),每天用作业将表的数据SWITCH到另一个分区表中。

    我的难题是:建有索引的表,每10多分钟就会产生15%-90%不等的索引碎片,这会导致WEB查询超时和写数据超时,不建索引又不行,因为在做UPDATE时,会先SELECT,然后做判断,有则UPDATE,无则INSERT。

    邹兄和大家有没有遇到类似的情况?有没有什么好的解决办法?为什么会有这么频繁的索引碎片?
    100  修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • dawugui
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    • 3

      3

    发表于:2008-02-22 22:16:561楼 得分:0
    删除索引,重建。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • pt1314917
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2008-02-22 22:17:012楼 得分:0
    外行人帮顶。。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • happyflystone
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    • 4

      5

    发表于:2008-02-22 22:17:263楼 得分:0
    估计是不合理的索引设计吧
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • dawugui
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    • 3

      3

    发表于:2008-02-22 22:17:504楼 得分:0
    INSERT的表每秒有几千条记录?

    个人认为sql server做不到.
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • liangCK
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    • 2

    发表于:2008-02-22 22:18:105楼 得分:0
    帮顶.接分.
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • dawugui
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    • 3

      3

    发表于:2008-02-22 22:21:016楼 得分:0
    如果真是每秒几千条记录,估计oracle也难搞.

    确实没搞过这么大的量.

    我最多也只在oracle上搞过每分钟5000条记录.

    帮顶.
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • scmyxj
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2008-02-22 22:26:427楼 得分:0
    删除索引重建,这种办法不行啊,重建索引会阻塞对数据的写操作。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • hb_gx
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2008-02-22 23:10:028楼 得分:0
    频繁更新的字段不适合建索引
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • fcuandy
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2008-02-22 23:16:589楼 得分:0
    同上.
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • w2jc
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2008-02-23 01:30:4610楼 得分:0
    如果楼主能使用2005企业版的话,可以使用它联机建索引的功能(只有企业版有这个功能)。
    大概原理就是SQL会保持现有一组索引,同时并行再建第二组索引,等第二组索引建好之后,自动把第一组索引换掉。
    这个过程中整个数据库一直是可用的。

    如果不能使用2005企业版的话,另外,还有一个办法是使用 DBCC INDEXDEFRAG,
    这个命令是2000和2005的其他版本里面唯一能在线清除索引碎片的命令。
    使用这个命令时,表还是可访问的。
    但这个命令没有完全重建索引(DBCC DBREINDEX)那么彻底,它不能更新表的统计信息。

    LZ可以考虑试试 DBCC INDEXDEFRAG
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • scmyxj
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2008-02-23 13:17:0411楼 得分:0
    我的数据库用的就是SQL SERVER2005,而我目前采用的对付索引碎片的办法就是做作业定期去Rebuild index,虽然这是联机操作,但我认为这不是解决问题的根本办法啊,而且我的作业定时居然要设置成20分钟才能完全对付索引碎片。大家还有没有从数据库的设计角度来解决这问题的办法呢?目前我用BLUK INSERT命令从txt文件中导入数据有时会超时,每次执行该命令的间隔是1个小时,这一个小时中,txt的文件大小达到30多M,而且是在应用层调用的该命令,大家看看是不是有什么解决办法呢?
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • qiyousyc
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2008-02-23 13:59:4312楼 得分:0
    调用数据前先删除索引,完成后Rebuild。不使用作业定期处理。
    感觉是你的结构流程设计肯定有问题。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • charry0110
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2008-02-23 16:22:4713楼 得分:0
    我们现在也在做一个导大量数据的项目,实用ado.net做的

    先是webservice传送,之后批量插入
    20000条数据要1分钟

    插入时用sqlbulkcopy
    更新时先删除在插入
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • charry0110
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2008-02-23 16:38:4714楼 得分:10
    测试局域网内的,就是除去webservice时间

    上面的实用单条

    40000条大约2秒,除去其他因素单纯插入数据
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • roy_88
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    • 2

      4

    发表于:2008-02-23 16:43:5215楼 得分:0
    选择空闲时间。。。
    优化索引。。
    http://topic.csdn.net/u/20070329/17/38398e78-adac-4d7e-a8b6-f2d319d283e8.html
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • bluestn
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2008-02-23 16:56:1416楼 得分:0
    个人认为这么大的数据更新量的系统,需要采取一些负载均衡的策略来讲压力分摊到多个服务器上面。
    否则确实很难承受那么大的数据量。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • jeakcowu
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2008-02-24 01:02:0717楼 得分:0
    TUDOX去完成吧。还有,服务器搞台P560以上的啊,或者集群咯+磁盘柜
    就几千条数据而言,采用先放入缓存里,等数据量达到5万后在一次性INSERT进去,估计会好点。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • w2jc
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2008-02-24 01:02:1118楼 得分:0
    我的难题是:建有索引的表,每10多分钟就会产生15%-90%不等的索引碎片,这会导致WEB查询超时和写数据超时,不建索引又不行,因为在做UPDATE时,会先SELECT,然后做判断,有则UPDATE,无则INSERT。
    -----------------------------------------------------------------------
    可能还要仔细考虑一下每个索引的填充因子(fillfactor)的值,一般默认是90%,
    你可以试试减小这个值到80%甚至75%,看看会不会好一些,但索引文件的体积会增加一些。

    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • zjcxc
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    • 2

      2

    发表于:2008-02-24 04:03:0319楼 得分:60
    我的难题是:建有索引的表,每10多分钟就会产生15%-90%不等的索引碎片,这会导致WEB查询超时和写数据超时,不建索引又不行,因为在做UPDATE时,会先SELECT,然后做判断,有则UPDATE,无则INSERT。
    ----------------------------------------------------------------------------------------------------------------

    如果这个是 UPDATE 造成的, 则一般在设计上应该做一些调整
    从理论上来讲, UPDATE 导致索引碎片主要是由于被 UPDATE 的记录的索引页存储不下 UPDATE 的结果, 导致页拆分而产生碎片
    因此, 除了如楼上所说, 应该适当降低索引的 FILLFACTOR 外
    还应该考虑修改表结构, 为列预留空间
    例如, 如果你的某个列存储的数据在 0-50 个字符之间, 从节约空间的角度来考虑, 一般设置会采用 varchar/nvarchar
    但如果这个列被频繁更新, 则可能会经常导致页拆分(旧的数据比新的数据短)
    在这种情况下, 应该考虑将列设置为 char/nchar, 这样空间是定长的, 无论新旧数据的实际长度如何, 它都是标准的 50 字符, 这样能够大大避免页拆分, 从而达到减少索引碎片的目的(在一定程度上对更新速度也有提高, 因为更新数据页的时候, 也同时避免了数据页的拆分)


    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • zjcxc
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    • 2

      2

    发表于:2008-02-24 04:08:2320楼 得分:0
    另外要考虑 CLUSTERED 索引(一般是主键) 的设计, 由于每个非 CLUSTERED 索引中都包含 CLUSTERED 索引的数据, 因此任何一个对 CLUSTERED 索引中的列的更新都会导致所有的非 CLUSTERED 索引被更新

    如果你的 UPDATE 经常有对 CLUSTERED 索引的更新, 则一般应该考虑更新 CLUSTERED 索引, 例如使用 标识列 这类列来做 CLUSTERED 索引.

    另外, 如果你的 CLUSTERED 索引的列长度较长, 一般也建议更换为使用 标识列 这类列来做 CLUSTERED 索引, 这样可以大大减少所有索引的存储空间, 这意味着 I/O 降低, 也就是索引检索效率提升

    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • zjcxc
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    • 2

      2

    发表于:2008-02-24 04:10:0021楼 得分:0
    则一般应该考虑更新  CLUSTERED  索引
                ^^^^^ 更换
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • jgchenhunter
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2008-02-24 08:42:5722楼 得分:20
    考虑更新 CLUSTERED 索引,索引列的太长更换为标示列

    最主要的是看产生碎片的谁产生的,根据产生的操作,进行处理,未必一定在数据库级别上来处理这个问题,也可以考据一下,在业务流程上进行优化,缓冲业务数据等

    我用的sql server2005 暂时还没有碰到这样的问题,期待你的解决,以做后人借鉴,我顶!!!!!
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • scmyxj
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2008-02-24 10:51:0923楼 得分:0
    非常感谢邹兄和大家的热心回复,我现在就准备按邹兄说的办法去调整,稍后我会附上结果。
    还有一个问题我也很奇怪,我的数据库中有一个表,我是按天分区的,共15个分区,此表我建了3个分区索引,而该表只进行BLUK INSERT操作,每次BLUK INSERT后,分区索引的碎片也非常大,而且15个分区的3个索引都有程度不等的碎片。这些碎片产生是不是和我上面的有些类似呢???
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • Sandy945
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2008-02-24 11:12:3824楼 得分:0
    学习`
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • zhangjjhua
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2008-02-24 11:49:0825楼 得分:0
      学习,,顶
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • w2jc
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2008-02-24 12:58:1326楼 得分:10
    每次BLUK  INSERT后,分区索引的碎片也非常大,而且15个分区的3个索引都有程度不等的碎片。这些碎片产生是不是和我上面的有些类似呢???
    --------------------------------
    三种基本操作:insert,update, delete中
    INSERT和UPDATE都会造成索引碎片,
    而且INSERT造成碎片的可能性更大,
    UPDATE的字段如果没有在索引中则不会影响索引,
    DELETE基本不会,但会造成索引空间利用不足。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • victorcai2006
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2008-02-24 17:41:5627楼 得分:0
    学习,顶
    修改 删除