大表频繁count的改进

当大表频繁需要count的查询,考虑使用汇总表。

比如,某个日志表记录了某个页面的点击记录,执行count可以得到总的点击数,由于数据量已经2.3亿条,每次count都要耗时6秒:

SELECT COUNT_BIG(1) FROM bigtable
SQL Server 执行时间:
   CPU 时间 = 14 毫秒,占用时间 = 6002 毫秒。

根据时间字段InsertTime统计发现,当天数据仅16852行,而历史数据约2.3亿

  • SELECT COUNT_BIG(1) FROM bigtable WHERE inserttime < '2020-01-01 00:00:00' --行数 234287003
  • SELECT COUNT_BIG(1) FROM bigtable WHERE inserttime >= '2020-01-01 00:00:00' --行数 16852

这种情况下,我们可以创建一个汇总表:

CREATE TABLE bigtable_summary(id int, dtime datetime, summ bigint)

第一次需要初始化数据,比如把2019年12月31日之前的数据全部初始化为一条记录:

DECLARE @cnt bigint
SET @cnt = (SELECT COUNT_BIG(1) FROM bigtable WHERE inserttime <= '2019-12-31 23:59:59')
INSERT INTO bigtable_summary(dtime, summ) VALUES('2019-12-31 59:59:59',@cnt)

以后每天00:00(比如2020-01-02)插入一条前一天的汇总记录,语法参考如下:

DECLARE @cnt bigint
SET @cnt = (SELECT COUNT_BIG(1) FROM bigtable WHERE inserttime >= '2020-01-01 00:00:00' AND inserttime < '2020-01-02 00:00:00')
INSERT INTO bigtable_summary(dtime, summ) VALUES('2020-01-01 00:00:00',@cnt)

这样可以大表的count就可以改为:汇总表sum汇总记录 + 大表当天的count记录,由于大表InsertTime字段有索引,只查询当天的数据,效率自然很高

$cnt1 = SELECT SUM(cnt) FROM bigtable_summary WHERE dtime < '2020-01-02 00:00:00'
$cnt2 = SELECT COUNT(1) FROM bigtable WHERE inserttime >= '2020-01-02 00:00:00'
$cnt = $cnt1 + $cnt2
Copyright © www.sqlfans.cn 2023 All Right Reserved更新时间: 2022-01-28 11:13:18

results matching ""

    No results matching ""