1

我尝试在 SQL 中记录所有内容,所以想添加一个名为的表log并在其中添加所有内容,该log表是:

  • ID唯一标识符——PK
  • LogDate日期时间PK
  • IPNVARCHAR
  • ActionNVARCHAR
  • InfoXML
  • UniqueID大整数

我记录每件事:登录,检查权限,查看页面,访问对象和..到这个表

然后我想还需要Some Log-Restore Implementations,所以有些日志记录是可恢复的,有些不是,Log表有大约800万条记录,但可恢复的记录大约有20万条,所以每次我们需要恢复时,都需要选择 8 百万,然后我决定添加新表并将可恢复的日志添加到这个新表log_restore::

  • ID唯一标识符
  • LogDate约会时间
  • IPNVARCHAR
  • ActionNVARCHAR
  • InfoXML
  • UniqueIDBIGINT--PK

好的,当我需要记录一切都很好。

但是当我需要查看日志时:该过程从log表中获取所有记录并将它们与log_restore表合并(联合)。

所以我需要加速这个过程而不影响插入(意味着不要减慢),这是我的想法:

  1. 添加记录时也log_restore将其添加到log表中(因此在选择中不需要联合)

  2. 使用此选择命令创建视图

  3. 添加简单数据类型列而不是 XML

  4. 在简单的 DataType 列上添加 Clustered PK LikeBIGINT

你有什么想法?有什么建议吗?

4

4 回答 4

6

一般来说,应该尽量少占用空间;它极大地有助于减少执行查询时的磁盘查找。并且比较较小的数据类型总是需要更少的时间!

可以对列进行以下调整:

  • 使用不可为空的列(减少存储空间,减少测试次数)
  • LogDate以时间戳(UNSIGNED INT,4 个字节)而不是 DATETIME(8 个字节)的形式存储
  • IP地址不应存储为 NVARCHAR;如果要存储 IPv4 地址,则 4 个字节就足够了(BINARY(4))。IPv6 支持需要 18 个字节 (VARBINARY(16))。同时,NVARCHAR 对于 IPv4 需要 30 个字节,对于 IPv6 需要 78 个字节......(在网上搜索 inet_ntoa、inet_aton、inet_ntop、inet_pton 以了解如何在地址的二进制和字符串表示之间切换)
  • 不要将相似的数据存储在两个单独的表中,而是添加一个RestorableBIT 类型的标志列,指示是否可以恢复日志条目
  • 您对该列的想法Info是正确的:最好使用 TEXT 或 NTEXT 数据类型
  • 而不是使用 NVARCHAR 类型Action,您可以考虑拥有一个Action包含所有可能操作的表(假设它们是有限数量的),并使用整数外键引用它们(int 越小越好)

索引优化也很重要。如果您的查询同时测试多个列,请在多个列上使用索引。例如,如果在一定的时间范围内选择特定IP对应的所有可恢复行,这将大大提高查询速度:

CREATE NONCLUSTERED INDEX IX_IndexName ON log (Restorable ASC, IP ASC, LogDate ASC)

如果您需要在给定的时间范围内从与特定操作对应的 IP 地址检索所有可恢复的行,则应选择以下索引:

CREATE NONCLUSTERED INDEX IX_IndexName ON log (IP ASC, Action ASC, LogDate ASC)

等等。

老实说,我实际上需要查看您的完整 SQL 查询才能进行适当的优化......

于 2013-06-25T22:59:11.900 回答
3

表格增强选项:

  1. 添加一Restorable bit null列并在其上创建过滤索引。

  2. 'XML' 数据类型是 LOB 数据类型,存储在行外。如果您不使用任何XML 数据类型方法,则不需要它。它确实会严重影响您的表现。添加XML_code varchar () null列并复制列中的所有数据XML

选择列的长度以保持最大行大小(所有列的总最大大小)小于 8Kb。Varchar (MAX)如果行适合 8kb,则列可以存储在行中。因此,如果您有大量的短 XML,那么VARCHAR (MAX)可以提供帮助。

  1. 如果您不使用 Unicode 数据,则将所有更改NVARCHARVARCHAR

  2. 将 aUNION ALLWherecluse 一起使用来过滤重复项,而不仅仅是UNION

  3. UNIQUEIDENTIFIER列在这里对您没有帮助。如果两条记录不能相同datetime(或者可能是datetime2) value, then it can you unique ID on its own. Alternatively consider changintID column toint as you order byint` 以合理的方式。

重新考虑您的想法:数字(4)无济于事。在两个表上创建索引,遵循 Where 子句和 JOIN 列。

进行多次迭代:简化数据类型 - 检查性能。创建索引 - 再次检查。等等。应该在最小化使用的空间和可用性之间取得平衡。您可能希望将一些数据保留在文本中,而不是编码为 int 或二进制。

使用 Profiler 或 Tuning advisor 来确定瓶颈和改进机会。

于 2013-06-25T08:13:28.107 回答
1

你首先要担心的是机器的内存,服务器有多少?那么您应该与您的数据库大小进行比较,或者可能只是您正在处理的表的大小。如果内存与表的大小相比太低,那么您必须向服务器添加更多内存。那是你要做的第一件事。

Microsoft SQL Server 内存的系统管理员指南

于 2013-06-26T13:48:53.400 回答
1

我将大胆猜测,标识某物是否“可恢复”的属性是Action列。如果是这种情况,则按该列对表进行分区并忘记该log_restore表。

MSDN -分区表和索引概念

于 2013-06-25T21:34:55.763 回答