`
h_rain
  • 浏览: 120620 次
  • 性别: Icon_minigender_1
  • 来自: 哈尔滨
文章分类
社区版块
存档分类
最新评论

对Berkeley DB的性能进行的部分测试

阅读更多

 

零 环境说明:
    所有的数据插入的都是Key=int,Value=int,在循环中递增的.
    本机NTFS的默认簇大小为4K.
    本机配置仅仅影响绝对值.相对值是可比较的:
        OS=WinXP SP2;RAM=1G;CPU=AMD Athlon 64 X2 Dual 5000+;Disk=160G  
    测试的实际数据量为:300*10000*2*sizeof(int)/1024/1024~=22.89MByte
    下面所有的测试结果的单位都是秒.
    编译器: C++ builder 6.0(使用bcb编译BDB源码,形成LIB库后,直接链接到测试程序中.没有测试DLL的形式.)
    BDB版本:4.6.21.NC

 

 一 测试页尺寸对读写性能的影响:
    记录数量 =300万 缓存尺寸=0M
读写\页尺寸 1K 2K 4K 8K 16K 32K
B+写 94.94 84.83 82.73 97.16 142.67 232.11
HASH写 346.16 320.41 288.36 295.19 599.66 867.03
B+读 4.22 4.06 3.86 3.91 3.80 3.78
HASH读 8.25 7.94 5.42 5.41 4.99 4.88

结论:页尺寸与文件系统的簇大小相同时,写入性能最佳,读取性能中等.

在0M缓存的时候,B+的性能要比HASH好得多.

 

 

 二 测试cache缓存大小对读写性能的影响:
    记录数量=300万  页尺寸=4K   真实数据量=22.89MByte 数据库文件大小=80M
读写\缓存 0M 10M 20M 40M 80M 160M 320M
B+写 85.06 88.66   133.31   164.81   15.31   15.34   15.27
HASH写 292.91 224.47   180.76   95.28   20.11 20.06 20.05
B+读 3.98 4.17   4.86   9.56   3.83   3.81   3.80  
HASH读 5.53 5.83   5.83 8.16 5.20 5.08 5.16

 

    记录数量=600万  页尺寸=4K   真实数据量=45.78MByte 数据库文件大小=160M
读写\缓存 0M 40M 80M 160M 320M
B+写 259.39   1198.27   1017.94   34.59   34.30  
HASH写 1889.32   1279.95 563.12   40.67 40.89
B+读 7.89   14.02 22.84   7.97   8.03  
HASH读 11.17   16.81 11.66 10.39 10.88

 

结论:
    对于缓存大于数据库文件尺寸的时候,没有太多可说的,操作都在内存中,速度非常快.   
    对于大数据量的读取,两组对比都比较清晰的说明了一点:缓存的大小对读取记录的性能影响不是很大.
    对于大数据量的写入,缓存对性能的影响就非常可观了,基本可以肯定的是,HASH库缓存越大写入速度越快.   而奇怪的是,B+库在缓存不足的时候,性能反而比0缓存时还要差很多!!
    总的来说,在我的这些测试中,B+与HASH数据库的性能差异很大.
    对于缓存大于物理内存的情况未做测试,估计对性能不会有好的影响,毕竟在这种情况下,效率的瓶颈都是在磁盘的IO上.
测试的核心代码如下:
 
#include <db_cxx.h>
#define	DATABASE	"access.db"
//tcount=记录数为多少万次,DbType=数据库类型,psize=页尺寸K,csize=缓存尺寸M
void run(int tcount,DBTYPE DbType,size_t psize,size_t csize)
{
	remove(DATABASE);
	Db db(0, 0);

	db.set_errpfx("AccessExample");
	db.set_pagesize(1024*psize);
	db.set_cachesize(0, 1024*1024*csize, 0);
	db.open(NULL, DATABASE, NULL, DbType, DB_CREATE|DB_THREAD, 0664);

    int testcount=10000*tcount;
    size_t tick1=GetTickCount();
	for (int i=0;i<testcount;i++)
    {
		Dbt key(&i,sizeof(int));
		Dbt data(&i,sizeof(int));
		db.put(0, &key, &data, DB_NOOVERWRITE);
    }
    
    printf("插入结束 %d 万记录,全部用时:%.2f秒\r\n",tcount,(GetTickCount()-tick1)/(float)1000);
    tick1=GetTickCount();
	try
    {
		Dbc *dbcp;
		db.cursor(NULL, &dbcp, 0);
		Dbt key;
		Dbt data;
		while (dbcp->get(&key, &data, DB_NEXT) == 0)
        {
			key.get_data();
			data.get_data();
		}
		dbcp->close();
        printf("遍历结束 %d 万记录,全部用时:%.2f秒\r\n",tcount,(GetTickCount()-tick1)/(float)1000);
        db.sync(0);
	}
	catch (DbException &dbe) {}
	db.close(0);
}
  
分享到:
评论
4 楼 h_rain 2009-02-22  
结论:页尺寸与文件系统的簇大小相同时,写入性能最佳,读取性能中等.

缓存用尽后,性能的瓶颈就在于磁盘IO.
BDB内部对IO进行了优化,每次操作都是对"页尺寸"字节进行处理,就是说,读写10字节或100字节的时候,其实都是在"页尺寸"这么大的内存上进行读写,之后一次性将一个页写入磁盘.你给定的页尺寸是8k,但ntfs默认的"簇"大小是4k,所以这样的操作要跨簇进行,效率就低了.

建议根据文件系统的"簇"大小设置BDB的"页尺寸".
这样的话,耗时基本是定长的了.
3 楼 peter_wu 2009-02-20  
观察任务管理器,发现速度快的时候,cache还没有用完,没有IO操作。当内存不再增长,cache用完的时候,IO开始大量读取和写入,速度开始下降。原来如此啊。
2 楼 peter_wu 2009-02-20  
插入一个周期,10w 用时 0.00 秒
插入一个周期,10w 用时 0.92 秒
插入一个周期,10w 用时 1.09 秒
插入一个周期,10w 用时 1.11 秒
插入一个周期,10w 用时 1.14 秒
插入一个周期,10w 用时 1.16 秒
插入一个周期,10w 用时 1.19 秒
插入一个周期,10w 用时 1.14 秒
插入一个周期,10w 用时 1.19 秒
插入一个周期,10w 用时 1.20 秒
插入一个周期,10w 用时 1.20 秒
插入一个周期,10w 用时 1.28 秒
插入一个周期,10w 用时 1.22 秒
插入一个周期,10w 用时 1.17 秒
插入一个周期,10w 用时 1.20 秒
插入一个周期,10w 用时 1.19 秒
插入一个周期,10w 用时 1.20 秒
插入一个周期,10w 用时 1.26 秒
插入一个周期,10w 用时 1.24 秒
插入一个周期,10w 用时 1.16 秒
插入一个周期,10w 用时 1.17 秒
插入一个周期,10w 用时 1.38 秒
插入一个周期,10w 用时 1.19 秒
插入一个周期,10w 用时 1.20 秒
插入一个周期,10w 用时 1.16 秒
插入一个周期,10w 用时 1.19 秒
插入一个周期,10w 用时 1.17 秒
插入一个周期,10w 用时 1.22 秒
插入一个周期,10w 用时 1.17 秒
插入一个周期,10w 用时 1.20 秒
插入一个周期,10w 用时 1.22 秒
插入一个周期,10w 用时 1.28 秒
插入一个周期,10w 用时 1.19 秒
插入一个周期,10w 用时 1.33 秒
插入一个周期,10w 用时 1.19 秒
插入一个周期,10w 用时 1.23 秒
插入一个周期,10w 用时 1.22 秒
插入一个周期,10w 用时 1.20 秒
插入一个周期,10w 用时 1.22 秒
插入一个周期,10w 用时 1.23 秒
插入一个周期,10w 用时 1.42 秒
插入一个周期,10w 用时 1.22 秒
插入一个周期,10w 用时 1.19 秒
插入一个周期,10w 用时 1.27 秒
插入一个周期,10w 用时 5.84 秒
插入一个周期,10w 用时 9.52 秒
插入一个周期,10w 用时 14.03 秒
插入一个周期,10w 用时 15.39 秒
插入一个周期,10w 用时 16.44 秒
插入一个周期,10w 用时 20.39 秒
插入结束 500 万记录,全部用时:156.05秒
遍历结束 500 万记录,全部用时:14.11秒
请按任意键继续. . .
1 楼 peter_wu 2009-02-20  
我改了下代码,发现一个问题,随着时间推移,插入效率下降严重,请问是为什么。

#include <db_cxx.h>  
#include <Windows.h>
#define DATABASE    "access.db"  
void run(int tcount,DBTYPE DbType,size_t psize,size_t csize)  ;
void main(int argc,char * argv[])
{
	run(500,DB_BTREE,8,100);
}


//tcount=记录数为多少万次,DbType=数据库类型,psize=页尺寸K,csize=缓存尺寸M  
void run(int tcount,DBTYPE DbType,size_t psize,size_t csize)  
{  
	remove(DATABASE);  
	Db db(0, 0);  

	db.set_errpfx("AccessExample");  
	db.set_pagesize(1024*psize);  
	db.set_cachesize(0, 1024*1024*csize, 0);  
	db.open(NULL, DATABASE, NULL, DbType, DB_CREATE|DB_THREAD, 0664);  

	int testcount=10000*tcount;  
	size_t tick1=GetTickCount();  

	DWORD inlinetick=tick1;
	for (int i=0;i<testcount;i++)  
	{  
		Dbt key(&i,sizeof(int));  
		Dbt data(&i,sizeof(int));  
		db.put(0, &key, &data, DB_NOOVERWRITE);  
		if (i%100000==0)
		{
			printf("插入一个周期,10w 用时 %.2f 秒\n",(GetTickCount()-inlinetick)/(float)1000);
			inlinetick=GetTickCount();
		}
	}  

	printf("插入结束 %d 万记录,全部用时:%.2f秒\r\n",tcount,(GetTickCount()-tick1)/(float)1000);  
	tick1=GetTickCount();  
	try  
	{  
		Dbc *dbcp;  
		db.cursor(NULL, &dbcp, 0);  
		Dbt key;  
		Dbt data;  
		while (dbcp->get(&key, &data, DB_NEXT) == 0)  
		{  
			key.get_data();  
			data.get_data();  
		}  
		dbcp->close();  
		printf("遍历结束 %d 万记录,全部用时:%.2f秒\r\n",tcount,(GetTickCount()-tick1)/(float)1000);  
		db.sync(0);  
	}  
	catch (DbException &dbe) {}  
	db.close(0);  
}  

相关推荐

    Berkeley并发性能测试

    一个测试berkeleydb并发性能测试的实例,采用多线程并发访问,测试berkeleydb的性能,日志恢复等。

    BerkeleyDB测试程序

    BerkeleyDB测试程序 包含散列文件入库,和读取的速度的测试

    PerconaFT:PerconaFT是一种高性能的交易型键值存储

    PerconaFT作为共享库提供,其接口类似于Berkeley DB。 要构建完整MySQL产品,请参阅。 本文档仅涵盖PerconaFT。 建筑 PerconaFT使用CMake&gt; = 2.8.9构建。 建议使用源外版本。 您需要一个C ++ 11编译器,尽管仅测试...

    nosql 入门教程

    14.2 性能测试 237 14.2.1 50/50的读和更新 237 14.2.2 95/5的读和更新 237 14.2.3 扫描 238 14.2.4 可扩展性测试 238 14.2.5 Hypertable测试 238 14.3 背景比较 239 14.4 小结 240 第15章 共存 241 15.1 ...

    elixir:Elixir 交叉参考

    它使用 Git 作为源代码文件存储,使用 Berkeley DB 作为交叉引用数据。 在内部,它索引 Git blob而不是文件树,以避免重复工作和数据。 它有一个简单的数据结构(让人想起旧的 LXR 版本)来保持查询的简单和快速。 ...

    MyICQ是一套公开源代码的即时通讯软件

    4) 在VC的Tools-&gt;Options-&gt;Directories中设置好MySQL和BerkeleyDB的include和library路径 5) 在VC中打开myicq-win32/src/win32/myicq.dsw项目文件 6) 编译 --------- 8. TODO --------- 1) POP3邮件自动监测(插件)...

    即时通myicq源代码

    4) 在VC的Tools-&gt;Options-&gt;Directories中设置好MySQL和BerkeleyDB的include和library路径 5) 在VC中打开myicq-win32/src/win32/myicq.dsw项目文件 6) 编译 --------- 8. TODO --------- 1) POP3邮件自动监测(插件)...

    面向移动信息终端设备的嵌入式数据库设计和实现 (2003年)

    以移动信息终端设备为研究背景,在分析和研究通用数据库的基础上,设计实现了一个更为精简、高效并适合于资源...最后通过测试SeuicDB和BerkeleyDB的性能,表明该数据库的设计适用于嵌入式系统,具有很好的可移植性。

    操作系统(内存管理)

    接下来,我将一次一个部分地对该清单进行解释。 在大部分操作系统中,内存分配由以下两个简单的函数来处理: void *malloc(long numbytes):该函数负责分配 numbytes 大小的内存,并返回指向第一个字节的指针。 ...

    fix8:具有完整模式自定义,高性能和快速开发的现代开源C ++ FIX框架

    开源C ++ FIX引擎一个现代的开源C ++ FIX框架,具有完整的模式驱动的自定义,高性能和快速的应用程序开发。 该系统由一个用于生成C ++消息和字段编码器,解码器和实例化表的编译器组成。 一个运行时库来支持生成的...

    MySQL 5.1参考手册 (中文版)

    2.3.14. 在Windows环境下对MySQL安装的故障诊断与排除 2.3.15. 在Windows下升级MySQL 2.3.16. Windows版MySQL同Unix版MySQL对比 2.4. 在Linux下安装MySQL 2.5.在Mac OS X中安装MySQL 2.6. 在NetWare中安装MySQL 2.7....

    mysql官方中文参考手册

    2.3.14. 在Windows环境下对MySQL安装的故障诊断与排除 2.3.15. 在Windows下升级MySQL 2.3.16. Windows版MySQL同Unix版MySQL对比 2.4. 在Linux下安装MySQL 2.5.在Mac OS X中安装MySQL 2.6. 在NetWare中安装MySQL 2.7....

    MYSQL中文手册

    2.3.14. 在Windows环境下对MySQL安装的故障诊断与排除 2.3.15. 在Windows下升级MySQL 2.3.16. Windows版MySQL同Unix版MySQL对比 2.4. 在Linux下安装MySQL 2.5.在Mac OS X中安装MySQL 2.6. 在NetWare中安装MySQL...

    MySQL 5.1参考手册中文版

    2.3.14. 在Windows环境下对MySQL安装的故障诊断与排除 2.3.15. 在Windows下升级MySQL 2.3.16. Windows版MySQL同Unix版MySQL对比 2.4. 在Linux下安装MySQL 2.5.在Mac OS X中安装MySQL 2.6. 在NetWare中安装MySQL ...

    MySQL 5.1参考手册

    2.3.14. 在Windows环境下对MySQL安装的故障诊断与排除 2.3.15. 在Windows下升级MySQL 2.3.16. Windows版MySQL同Unix版MySQL对比 2.4. 在Linux下安装MySQL 2.5.在Mac OS X中安装MySQL 2.6. 在NetWare中安装MySQL 2.7....

    MySQL 5.1中文手冊

    2.3.14. 在Windows环境下对MySQL安装的故障诊断与排除 2.3.15. 在Windows下升级MySQL 2.3.16. Windows版MySQL同Unix版MySQL对比 2.4. 在Linux下安装MySQL 2.5.在Mac OS X中安装MySQL 2.6. 在NetWare中安装MySQL 2.7....

    MySQL5.1参考手册官方简体中文版

    2.3.14. 在Windows环境下对MySQL安装的故障诊断与排除 2.3.15. 在Windows下升级MySQL 2.3.16. Windows版MySQL同Unix版MySQL对比 2.4. 在Linux下安装MySQL 2.5.在Mac OS X中安装MySQL 2.6. 在NetWare中安装MySQL 2.7....

    mysql5.1中文手册

    MySQL对标准SQL的扩展 1.8.5. MySQL与标准SQL的差别 1.8.6. MySQL处理约束的方式 2. 安装MySQL 2.1. 一般安装问题 2.1.1. MySQL支持的操作系统 2.1.2. 选择要安装的MySQL分发版 2.1.3. 怎样...

    MySQL 5.1官方简体中文参考手册

    2.3.14. 在Windows环境下对MySQL安装的故障诊断与排除 2.3.15. 在Windows下升级MySQL 2.3.16. Windows版MySQL同Unix版MySQL对比 2.4. 在Linux下安装MySQL 2.5.在Mac OS X中安装MySQL 2.6. 在NetWare中安装MySQL ...

Global site tag (gtag.js) - Google Analytics