count, sum, avg by range in log(n) time
2010-02-05 15:40
344 查看
考虑一下这样一个查询:
select count(*), sum(tax), avg(weight)
from pepole
where id >= ${minid} && id < ${maxid};
怎样才能实现更小的时间复杂度?
一般情况下,最简单的方法就是遍历这个区间。但是这需要O(logn +m)的时间复杂度,其中m是区间长度,n是总记录数。
实际上,可以略增一点存储代价,对该查询实现O(logn)的时间复杂度。我以前写过一篇文章
,可以对count(*)实现logn复杂度:
count(*, minid, maxid) = rank(maxid) - rank(minid)
其中,rank(id) 表示该记录在整个表中的序号(排序名词)。这很容易理解。
如果要计算sum(x)或avg(x),需要扩张一下,在每个结点中存储一个隐藏值,用来表示该以结点为根的子树的sum(x)值,那么,插入/删除/修改的代价也是O(logn),计算sum(x),avg(x)的代价也是O(logn)。
sum(x, minid, maxid) = node(maxid).hidesumx - node(minid).hidesumx
avg(x, minid, maxid) = sum(x)/count(*, minid, maxid)
BekeleyDB中,可以实现 count(*) 的log(n)时间复杂度,因为它提供了类似rank()函数的功能,使用btree表,建表时提供DB_RECNUM标志。查询时,使用DBC::get,用DB_GET_RECNO flag:
select count(*), sum(tax), avg(weight)
from pepole
where id >= ${minid} && id < ${maxid};
怎样才能实现更小的时间复杂度?
一般情况下,最简单的方法就是遍历这个区间。但是这需要O(logn +m)的时间复杂度,其中m是区间长度,n是总记录数。
实际上,可以略增一点存储代价,对该查询实现O(logn)的时间复杂度。我以前写过一篇文章
,可以对count(*)实现logn复杂度:
count(*, minid, maxid) = rank(maxid) - rank(minid)
其中,rank(id) 表示该记录在整个表中的序号(排序名词)。这很容易理解。
如果要计算sum(x)或avg(x),需要扩张一下,在每个结点中存储一个隐藏值,用来表示该以结点为根的子树的sum(x)值,那么,插入/删除/修改的代价也是O(logn),计算sum(x),avg(x)的代价也是O(logn)。
sum(x, minid, maxid) = node(maxid).hidesumx - node(minid).hidesumx
avg(x, minid, maxid) = sum(x)/count(*, minid, maxid)
BekeleyDB中,可以实现 count(*) 的log(n)时间复杂度,因为它提供了类似rank()函数的功能,使用btree表,建表时提供DB_RECNUM标志。查询时,使用DBC::get,用DB_GET_RECNO flag:
DB_ENV** dbenv; DB* db; /*.....*/ db_create(&db, dbenv, 0); db->open(db, NULL, "tablename", "filename", DB_BTREE, DB_CREATE, 0); db->set_flags(db, DB_RECNUM); /*.....*/ int get_rank(DB* db, const void* key, size_t klen, db_recno_t* rank) { int ret; DBC* curp; DBT key = {0}, data = {0}, ignore = {0}, recno = {0}; key.data = key; key.size = klen; recno.data = rank; recno.size = sizeof(*rank); ret = curp->get(curp, &key, &data, DB_SET); if (0 == ret) { ret = curp->get(curp, &ignore, &recno, DB_GET_RECNO); } return ret; }
相关文章推荐
- count, sum, avg by range in log(n) time
- linq to sql (Group By/Having/Count/Sum/Min/Max/Avg操作符) (转帖)
- LINQ to SQL语句(3)之Count/Sum/Min/Max/Avg
- 单表-------主键、外键、选择操作,like操作符,in 批量查询、排序order by、表的复杂查询---分组函数(max/min/agv/sum/count)、group by、having
- Oracle分析函数三——SUM,AVG,MIN,MAX,COUNT
- 大数据Spark “蘑菇云”行动第47课程 Spark 2.0实战之Dataset:collect_list、collect_set、avg、sum、countDistinct等
- stringByReplacingCharactersInRange: withString: 实现字符串删除,替换
- Sum All Numbers in a Range
- OGG-00685 begin time <time> prior to oldest log in log history
- 聚合函数:sum,avg,max,min,count;模糊查询;排序
- []LeetCode]Count of Range Sum
- LINQ体验(四)——LINQ to SQL语句之Select/Distinct和Count/Sum/Min/Max/Avg
- MySQL学习足迹记录10--汇总数据--MAX(),MIN(),AVG(),SUM(),COUNT()
- sql server group by 分组带sum avg求和需要注意的一点
- Hibernate 使用 count(*)、avg、sum
- linq to sql 用法 ----- count/sum/min/max/avg
- MDX Step by Step 读书笔记(七) - Performing Aggregation 聚合函数之 Sum, Aggregate, Avg
- LINQ to SQL语句之Select/Distinct和Count/Sum/Min/Max/Avg
- iOS开发经验技巧之stringByReplacingCharactersInRange: withString: 實現字符串删除,替换
- Leetcode #327 Count of Range Sum