假设索引已经到位,并且绝对计数准确性不是必需的(可以关闭一两个),是否可以使用:
select count(*)
from Table
where Property = @Property
VS
update PropertyCounters
SET PropertyCount = PropertyCount + 1
where Property = @Property
然后做:
select PropertyCount
from PropertyCounters
where Property = @Property
当表格增长到数千/数百万条记录时,我可以合理地期望从选择计数(*)中获得多少性能下降?
答案 0 :(得分:4)
除了真实数据之外,保持单独的计数列是非规范化。你有可能需要为性能做这件事,但你不应该去那里直到你真的需要。它使你的代码更复杂,更容易出现不一致的情况。
对于查询确实只是SELECT COUNT(property) FROM table WHERE property=...
的简单情况,没有理由去反规范化;您可以通过在property
列上添加索引来加快速度。
答案 1 :(得分:3)
您没有指定平台,但由于您使用@variables的T-SQL语法,我将冒险尝试SQL Server平台特定答案:
count(*)
,或严格来说是count_big(*)
,是一个可以在索引视图中使用的表达式,请参阅Designing Indexed Views。
create view vwCounts
with schembinding
as select Property, count_big(*) as Count
from dbo.Table
group by Property;
create unique clustered index cdxCounts on vwCounts(Property);
select Count
from vwCount with (noexpand)
where Property = @property;
在Enterprise Edition上,优化器甚至会使用原始查询的索引视图:
select count_big(*)
from Table
where Property = @property;
所以最后你得到你的蛋糕并吃掉它:该物业已经由发动机免费聚集和维护。价格是更新必须维护索引视图(他们将不重新计算聚合计数),聚合将创建争用的热点(表上的单独行上的锁将争用相同的计数( *)更新索引视图。
答案 2 :(得分:1)
如果你说你不需要绝对的准确性,那么选项B是一种奇怪的方法。如果选项A变得太重(甚至在添加索引之后),您可以将选项A的输出缓存在内存或另一个表(您的PropertyCounters)中,并定期刷新它。
答案 3 :(得分:0)
这不是一般SQL术语中可以回答的问题。除了关于索引等关于影响查询的常规警告之外,它也是平台之间存在相当大差异的东西。
我敢打赌从SQL Server上获得比Postgres更好的性能,直到我在Postgres上考虑后一种方法,而不是在SQL Server上。但是,如果部分索引设置恰好匹配条件,我会打赌Postgres击败SQL Server。这就是我敢打赌的小奖金,不管怎么说,如果我需要考虑它是真的,我会测试。
如果您采用后一种方法,请使用触发器或类似方法强制执行,以免您变得不准确。
答案 4 :(得分:0)
在SQL Server上,如果您不需要绝对准确的计数,您还可以检查目录视图。这样做会容易得多 - 你不必自己计算 - 而且对系统的负担要少得多。毕竟,如果你需要计算表中的所有行,你需要以某种方式扫描该表 - 没有办法解决这个问题。
使用此SQL语句,您将获得数据库中的所有表以及SQL Server保留的行数:
SELECT
t.NAME AS TableName,
SUM(p.rows) AS RowCounts
FROM
sys.tables t
INNER JOIN
sys.indexes i ON t.OBJECT_ID = i.object_id
INNER JOIN
sys.partitions p ON i.object_id = p.OBJECT_ID AND i.index_id = p.index_id
WHERE
t.NAME NOT LIKE 'dt%' AND
i.OBJECT_ID > 255 AND
i.index_id <= 1
GROUP BY
t.NAME, i.object_id, i.index_id, i.name
ORDER BY
OBJECT_NAME(i.object_id)
我找不到任何关于目前这些数字究竟是多少的文档 - 通常 - 但根据我自己的经验,他们通常是在现场(除非你正在做一些批量加载或其他东西 - 但在这种情况下,您不希望不断扫描表格以获得准确的计数,或者