如何在使用或不使用NoSql的情况下解决日志缓慢问题



我在日志搜索速度和磁盘大小方面遇到问题。它非常大,大约有2.2亿行,25 GB的磁盘大小,需要几分钟才能提取一些选择。

它是如何工作的?日志使用Sql Anywhere保存在数据库中,当前版本为9,很快将迁移到11(我们尝试迁移到12,但由于一些驱动程序和一些问题,我们返回到11)。

日志由两个表组成(名称改为英文,以便这里的人能够理解):

日志表

Id、DateTime、User、Url、Action和TableName操作是所使用的操作:插入/删除/更新TableName是数据库中受影响的表。

日志表字段

Id、LogTable_Id、FieldName、NewValue、OldValueLogTable_Id是LogTable中的外键。FieldName是DB中表的字段。

需要注意的是,NewValue和OldValue是varchar的类型。因为它记录了其他表中的各种字段(datetime、int等)。

为什么要这样做因为我们必须记录所有重要的事情。该系统是为机构交通部设计的(我不知道它在正确的英语中是否是这样拼写的,但现在你可以知道这是关于什么的),有时他们要求某种随机报告。

到目前为止,我们的报告只是做了一些SQL选择。但是,即使过滤了日期时间,也需要几分钟才能完成。不是和问题抱怨时,它不经常要求。

但他们要求越来越多的报告,即有必要在软件中创建一个具有漂亮报告的功能。由于我们永远不知道他们的需求,我们必须回去记录并卸载数据。

请求的某些信息仅在日志中。(例如,什么用户向某人提供了不正当的车辆访问权限)

迄今为止提出的一些想法:

想法1:我做了一些研究,并被告知使用CouchDB与NoSql合作。但我读到的一点点内容让我觉得NoSql并不能解决我的问题。我无法解释为什么没有经验。

想法2:将日志表与数据库或机器物理分离。

想法3:从每个表中创建一个带有版本字段的镜像,以保存历史记录。

如果需要的话,我想进行宏观优化或架构更改。

这似乎是一个非常标准的审计表。我不确定您是否需要为此使用NoSQL解决方案。2.2亿行将由大多数RDBM轻松处理。

看来最大的问题是表的结构。通常情况下,您可以压平表以提高日志记录速度,并将其规范化以提高报告速度。正如你所看到的,这些是相互冲突的。

如果您使用的是类似MSSQL的东西,您可以为日志记录性能构建一个单一的平面表,然后在其上构建一个简单的AnalysisServices多维数据集

另一种选择是,假设您可以保持足够的日志吞吐量,则只对报告进行优化。要做到这一点,您可能需要创建这样一个结构:

创建表LogTable(LogTableID int恒等式(1,1),TableName varchar(100),Url varchar(200))创建表LogUser(LogUserID int identity(1,1),用户名varchar(100))创建表LogField(LogFieldID int恒等式(1,1),FieldName varchar(100),)创建表LogData(LogDataID bigint恒等式(1,1),日志日期时间,LogTableID int引用LogTable(LogTableID),LogFieldID int引用LogField(LogFieldID),LogUserID int引用LogUserID(LogUserID),操作字符(1),--U=更新,I=插入,D=删除OldValue varchar(100),NewValue varchar(100))

这仍然应该足够快,可以快速记录数据,但为报告提供足够的性能。索引设计也很重要,通常是按照基数增加的顺序进行的,比如LogData(LogTableID、LingFieldID、LogDate)。您还可以通过分区来实现并行查询。

添加适当的索引将是您能做的最大改进。你没有提到有任何指数,所以我想你没有。这会使它非常缓慢。

例如,除非在DateTime上有索引,否则将查询限制在特定的DateTime范围内根本没有帮助。如果没有索引,数据库仍然需要接触几乎所有25GB的数据,才能找到在正确时间范围内的几行。但有了索引,它可以快速识别出您关心的时间范围内的几行。

通常,您应该始终询问数据库,它使用什么计划来执行耗时过长的查询。我对SqlAnywhere不是特别熟悉,但我知道它有一个可以做到这一点的Plan Viewer。您想要识别大的顺序扫描,并将索引放在这些字段上。

我怀疑您是否会从分解表和使用整数外键中看到可衡量的改进。如果您的查询涉及多个列,那么您最终只会将所有这些表重新连接在一起。

相关内容

最新更新