存储大型 SQL 数据的查询和计数的最有效方式
Posted
技术标签:
【中文标题】存储大型 SQL 数据的查询和计数的最有效方式【英文标题】:Most efficient way to store queries and counts of large SQL data 【发布时间】:2011-08-08 14:15:37 【问题描述】:我有一个包含大量数据的 SQL Server 数据库(6500 万行主要是文本,总共 8Gb)。数据每周仅更改一次。我有一个 ASP.NET Web 应用程序,它将对该数据运行几个 SQL 查询,这些查询将计算满足各种条件的行数。由于数据每周只更改一次,那么存储 SQL 查询及其一周计数的最有效方法是什么?我应该将它存储在数据库中还是应用程序中?
【问题讨论】:
顺便说一句,6500 万行和总共 8GB 并不是那么大...... MS SQL Server 是否支持物化视图?那将是一个想法。 (我快速搜索了一下,发现this。) 【参考方案1】:如果数据每周只修改一次,作为该(ETL?)过程的一部分和结束时,执行您的“基本”计数并将结果存储在数据库中的表中。此后,您可以只查询那些小的汇总表,而不是对大表进行冗长的查询。
【讨论】:
【参考方案2】:如果您不需要 100% 最新的准确行数,您可以查询 SQL Server 的内部信息:
Select so.name as 'TableName', si.rowcnt as 'RowCount'
from sysobjects so
inner join sysindexes si on so.id = si.id
where so.type = 'u' and indid < 2
执行速度非常快,不需要额外的表格。在发生许多更新的地方不准确,但可能在您的预期用途中足够准确。 [感谢评论者!]
更新:进行了一些挖掘,这确实产生了准确的计数(由于总和而变慢,但仍然很快):
SELECT OBJECT_SCHEMA_NAME(ps.object_id) AS SchemaName,
OBJECT_NAME(ps.object_id) AS ObjectName,
SUM(ps.row_count) AS row_count
FROM sys.dm_db_partition_stats ps
JOIN sys.indexes i ON i.object_id = ps.object_id
AND i.index_id = ps.index_id
WHERE i.type_desc IN ('CLUSTERED','HEAP')
AND OBJECT_SCHEMA_NAME(ps.object_id) <> 'sys'
GROUP BY ps.object_id
ORDER BY OBJECT_NAME(ps.object_id), OBJECT_SCHEMA_NAME(ps.object_id)
Ref.
请记住,存储的计数信息并不总是 100% 在 SQL Server 2000 中准确。对于 2005 年创建的新表 计数将是准确的。但是对于 2000 年和现在存在的表 通过还原或更新驻留在 2005 上,您需要运行(仅 移至 2005 年之后一次) sp_spaceused @updateusage = N'true' 或带有 COUNT_ROWS 选项的 DBCC UPDATEUSAGE。
【讨论】:
我不完全相信这些查询的结果总是 100% 准确,即使我自己使用它们。是否有证据证明这一点,一种或另一种方式? 如果频繁更改,元数据行数并非 100% 准确。对于 OP 的情况(每周更新),它们不太可能不准确。 @mitch - sysindexes 仅与当前统计数据一样准确。 @mitch - 我也是。我从多个其他来源阅读过它,而不是来自 MSDN。我们需要像 Remus 这样的人过来确认一下。【参考方案3】:查询应存储为存储过程或视图,具体取决于复杂性。
对于您的情况,我会调查indexed views.
它们让您既可以存储查询,也可以存储结果集,以用于聚合等否则无法索引的内容。
作为奖励,查询优化器“知道”它也有这些数据,因此如果您在另一个查询中检查计数或存储在视图索引中的其他内容(即使是不直接引用视图),它仍然可以使用存储的数据。
【讨论】:
索引视图可能非常有用,但我认为在这种情况下它们是多余的。 @Mitch - 也许吧。他没有说他需要多久检查一次这些聚合,或者有多少,或者结果中有多少查询活动。以上是关于存储大型 SQL 数据的查询和计数的最有效方式的主要内容,如果未能解决你的问题,请参考以下文章