Jan*_*oom 10 sql-server database-design bigtable
前段时间,我想为一个新的统计系统,为我们的数百万用户网站,为我们的客户记录和报告用户操作.
数据库设计非常简单,包含一个表,一个foreignId(200,000个不同的id),一个datetime字段,一个actionId(30个不同的id),还有两个包含一些元信息的字段(只是smallint).其他表没有约束.此外,我们有两个索引,每个索引包含4个字段,无法删除,因为当我们有较小的索引时,用户会收到超时.foreignId是最重要的字段,因为每个查询都包含此字段.
我们之所以选择使用SQL服务器,但是在实现之后关系数据库看起来并不完美,因为我们不能每天插入3000万条记录(它只是插入,我们不做任何更新),而且还做了很多随机读取数据库; 因为索引无法快速更新.Ergo:我们有一个大问题:-)我们暂时解决了这个问题
关系数据库似乎不适合这个问题!
像BigTable这样的数据库会是更好的选择,为什么?或者在处理这类问题时还有其他更好的选择吗?
NB.此时我们使用单个8核Xeon系统,4 GB内存和Win 2003 32位.据我所知,RAID10 SCSI.索引大小约为表大小的1.5倍.
Rem*_*anu 11
您说您的系统能够在没有索引的情况下每秒插入3000条记录,但只有大约100条记录,并且有两个额外的非聚集索引.如果3k/s是I/O允许的最大吞吐量,那么在理论上添加两个索引应该会将吞吐量降低到大约1000-1500 /秒.相反,你会看到降级10倍.正确的解决方案和答案是"它依赖",并且必须进行一些严重的故障排除和瓶颈识别.考虑到这一点,如果我冒险猜测,我会给两个可能的罪魁祸首:
A.其他非聚集索引将脏页的写入分配到更多分配区域.解决方案是将聚簇索引和每个非聚集索引放入其自己的文件组中,并将三个文件组分别放在RAID上的不同LUN上.
B.非聚簇索引的低选择性会在读取和写入之间产生高争用(键冲突以及%lockres%冲突),从而导致插入和选择的锁定等待时间过长.可能的解决方案是使用带有读提交快照模式的 SNAPSHOT ,但我必须警告在可能已经处于高IO压力下的系统中在版本存储中添加大量 IO (即在tempdb中)的危险.第二种解决方案是使用数据库快照进行报告,它们可以降低IO压力并且可以更好地控制它们(不涉及tempdb版本存储),但报告不再是实时数据.
我倾向于认为B)是可能的原因,但我必须再次强调需要进行适当的调查和适当的根案例分析.
'RAID10'不是一个非常精确的描述.
至于关系数据库是否适合这样的问题,是的,绝对的.还有许多因素需要考虑,可恢复性,可用性,工具集生态系统,专有技术专业知识,易于开发,易于部署,易于管理等等.关系数据库可以轻松处理您的工作负载,只需要进行适当的调整即可.每天3000万次插入,每秒350次,是数据库服务器的小改动.但是无论CPU数量多少,32位4GB RAM系统都不是数据库服务器.
听起来你可能会遇到两个特殊的问题.您遇到的第一个问题是您的索引每次执行插入时都需要重建 - 您是否真的尝试运行事务服务器的实时报告(这通常被认为是禁止)?其次,您可能遇到服务器必须调整数据库大小的问题 - 检查以确保您已分配足够的空间并且不依赖数据库为您执行此操作.
您是否考虑过在SQL Server中查找类似索引的视图?它们是从主表中删除索引并将其移动到物化视图的好方法.