事情紧急,期待大家和邹兄的解答!非常频繁且大数据量的向表中写数据,导致有索引的表的索引碎片增长很快。。。。

scmyxj 2008-02-22 10:14:37
现在有一系统,数据库中的其中几个表会被很频繁地INSERT,有几个表会被很频繁地UPDATE和INSERT,
这些表的数据量非常大(INSERT的表每秒有几千条记录,UPDATE和INSERT的表每秒的记录稍小一点),
我现在采用的办法是,做INSERT的表没有建索引,是按天分区且只保留最近15天的记录,做UPDATE和INSERT的表建有索引(个数为1-4个),每天用作业将表的数据SWITCH到另一个分区表中。

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

邹兄和大家有没有遇到类似的情况?有没有什么好的解决办法?为什么会有这么频繁的索引碎片?
...全文
462 32 打赏 收藏 转发到动态 举报
写回复
用AI写文章
32 条回复
切换为时间正序
请发表友善的回复…
发表回复
photojjc 2008-02-29
  • 打赏
  • 举报
回复
mark
dobear_0922 2008-02-27
  • 打赏
  • 举报
回复
关注
lainY7mail 2008-02-27
  • 打赏
  • 举报
回复
期待常出现这样的帖子
rqrq 2008-02-27
  • 打赏
  • 举报
回复
mark,学习。
w2jc 2008-02-24
  • 打赏
  • 举报
回复
每次BLUK INSERT后,分区索引的碎片也非常大,而且15个分区的3个索引都有程度不等的碎片。这些碎片产生是不是和我上面的有些类似呢???
--------------------------------
三种基本操作:insert,update, delete中
INSERT和UPDATE都会造成索引碎片,
而且INSERT造成碎片的可能性更大,
UPDATE的字段如果没有在索引中则不会影响索引,
DELETE基本不会,但会造成索引空间利用不足。
zhangjjhua 2008-02-24
  • 打赏
  • 举报
回复
学习,,顶
阿非 2008-02-24
  • 打赏
  • 举报
回复
学习`
scmyxj 2008-02-24
  • 打赏
  • 举报
回复
非常感谢邹兄和大家的热心回复,我现在就准备按邹兄说的办法去调整,稍后我会附上结果。
还有一个问题我也很奇怪,我的数据库中有一个表,我是按天分区的,共15个分区,此表我建了3个分区索引,而该表只进行BLUK INSERT操作,每次BLUK INSERT后,分区索引的碎片也非常大,而且15个分区的3个索引都有程度不等的碎片。这些碎片产生是不是和我上面的有些类似呢???
jgchenhunter 2008-02-24
  • 打赏
  • 举报
回复
考虑更新 CLUSTERED 索引,索引列的太长更换为标示列

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

我用的sql server2005 暂时还没有碰到这样的问题,期待你的解决,以做后人借鉴,我顶!!!!!
Name 2008-02-24
  • 打赏
  • 举报
回复
呵呵,

学习一下。

victorcai2006 2008-02-24
  • 打赏
  • 举报
回复
学习,顶
zjcxc 元老 2008-02-24
  • 打赏
  • 举报
回复
则一般应该考虑更新 CLUSTERED 索引
^^^^^ 更换
zjcxc 元老 2008-02-24
  • 打赏
  • 举报
回复
另外要考虑 CLUSTERED 索引(一般是主键) 的设计, 由于每个非 CLUSTERED 索引中都包含 CLUSTERED 索引的数据, 因此任何一个对 CLUSTERED 索引中的列的更新都会导致所有的非 CLUSTERED 索引被更新

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

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

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

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



w2jc 2008-02-24
  • 打赏
  • 举报
回复
我的难题是:建有索引的表,每10多分钟就会产生15%-90%不等的索引碎片,这会导致WEB查询超时和写数据超时,不建索引又不行,因为在做UPDATE时,会先SELECT,然后做判断,有则UPDATE,无则INSERT。
-----------------------------------------------------------------------
可能还要仔细考虑一下每个索引的填充因子(fillfactor)的值,一般默认是90%,
你可以试试减小这个值到80%甚至75%,看看会不会好一些,但索引文件的体积会增加一些。

jeakcowu 2008-02-24
  • 打赏
  • 举报
回复
TUDOX去完成吧。还有,服务器搞台P560以上的啊,或者集群咯+磁盘柜
就几千条数据而言,采用先放入缓存里,等数据量达到5万后在一次性INSERT进去,估计会好点。
码农心语 2008-02-23
  • 打赏
  • 举报
回复
个人认为这么大的数据更新量的系统,需要采取一些负载均衡的策略来讲压力分摊到多个服务器上面。
否则确实很难承受那么大的数据量。
中国风 2008-02-23
  • 打赏
  • 举报
回复
选择空闲时间。。。
优化索引。。
http://topic.csdn.net/u/20070329/17/38398e78-adac-4d7e-a8b6-f2d319d283e8.html
晓风残月0110 2008-02-23
  • 打赏
  • 举报
回复
测试局域网内的,就是除去webservice时间

上面的实用单条

40000条大约2秒,除去其他因素单纯插入数据
晓风残月0110 2008-02-23
  • 打赏
  • 举报
回复
我们现在也在做一个导大量数据的项目,实用ado.net做的

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

插入时用sqlbulkcopy
更新时先删除在插入
加载更多回复(12)

34,594

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server相关内容讨论专区
社区管理员
  • 基础类社区
  • 二月十六
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧