申请会员账号:54dabang
1、申 请 I D:54dabang2、个人邮箱:leixingbang@163.com
3、一篇原创技术文章: TPC-H测试 (用来做数据库系统测试、计算机集群测试)博客链接:http://blog.csdn.net/leixingbang1989/article/details/8766047 看链接名称就知道是我自己写的了,在csdn上写了接近一百篇技术博客,这篇文章是根据官方纯英文文档而写,百度tpc-h教程搜到的第一篇即为我的博客
TPC-H简介 以及DBGEN QGEN的使用 作者:54dabang 联系方式:leixingbang@163.com引言: 在实验室时候,由于老师需要用到TPC的相关知识,于是让我做一下关于TPC-H的研究。通过百度检索以及相关资料查询,发现目前国内做的相关研究特别少,而且介绍的也非常模糊,而TPC-H的英文使用说明多达两百多页,对于其中重要的QGEN DBGEN的使用根本没有介绍。 特此写下此文章,希望能帮助初期研究的同学,也希望做TPC方面研究的同学能少走一些弯路。Tpc-H中文文档翻译TPC简介事务处理性能委员会( Transaction ProcessingPerformance Council ),是由数10家会员公司创建的非盈利组织,总部设在美国。该组织对全世界开放,但迄今为止,绝大多数会员都是美、日、西欧的大公司。TPC的成员主要是计算机软硬件厂家,而非计算机用户,它的功能是制定商务应用基准程序(Benchmark)的标准规范、性能和价格度量,并管理测试结果的发布。TPC- C 用于测试数据库系统的事务处理能力,TPC- App 用于测试7×24 环境下B2B 的应用服务和Web 服务的能力。TPC 组织还发布过TPC- S(Server 专门测试基准程序)、TPC- E(大型企业信息服务测试基准程序)和TPC- Client/Server等测试标准,但这3 个标准不被业界接受而被放弃。TPC不给出基准程序的代码,而只给出基准程序的标准规范(Standard Specification)。任何厂家或其它测试者都可以根据规范,最优地构造出自己的系统(测试平台和测试程序)。(需要自己写测试工具,测试完之后提交给TPC协会)为保证测试结果的客观性,被测试者(通常是厂家)必须提交给TPC一套完整的报告(FullDisclosure Report),包括被测系统的详细配置、分类价格和包含五年维护费用在内的总价格。该报告必须由TPC授权的审核员核实(TPC本身并不做审计),现在全球只有不到十个审核员,全部在美国。(测试价格昂贵的原因)TPC目前推出的基准程序TPC推出过11套基准程序,分别是正在使用的TPC-App、TPC-H、TPC-C、TPC-W,过时的TPC-A、TPC-B、TPC-D和TPC-R,以及因为不被业界接受而放弃的TPC-S(Server专门测试基准程序)、TPC-E(大型企业信息服务测试基准程序)和TPC-Client/Server。这里重点介绍TCP-H。TPC-H的目的TPC- H 主要目的是评价特定查询的决策支持能力,强调服务器在数据挖掘、分析处理方面的能力。查询是决策支持应用的最主要应用之一,数据仓库中的复杂查询可以分成两种类型:一种是预先知道的查询,如定期的业务报表;另一种则是事先未知的查询,称为动态查询(Ad- Hoc Query)。通俗的讲,TPC-H就是当一家数据库开发商开发了一个新的数据库操作系统,采用TpC-H作为测试基准,来测试衡量数据库操作系统查询决策支持方面的能力.TPC-H的衡量指标它模拟决策支持系统中的数据库操作,测试数据库系统复杂查询的响应时间,以每小时执行的查询数(TPC-H QphH@Siz)作为度量指标.TPC-H标准规范TPC- H 标准规范由10 章正文和5 个附录组成。详细内容见:tpch2.14.4.docx数据库运行的环境条件TPC- H 测试模型为数据库服务器连续7×24 小时工作,可能只有1 次/月的维护;多用户并发执行复杂的动态查询,同时有并发执行表修改操作。数据库模型见图1,共有8 张表,除Nation 和Region 表外,其它表与测试的数据量有关,即比例因SF(Scale Factor)数据库关系图以及表各个字段定义如下图具体表中各个字段的定义,请参阅TPC-H标准规范。
数据库模型
数据量规定
由于数据量的大小对查询速度有直接的影响,TPC- H 标准对数据库系统中的数据量有严格、明确的规定。用SF 描述数据量,1SF 对应1 GB 单位,SF 由低到高依次是1、10、30、100、300、1 000、3 000、10 000。需要强调,SF 规定的数据量只是8个基本表的数据量,不包括索引和临时表。从TPC- H 测试全程来看,需要的数据存储空较大,一般包括有基本表、索引、临时表、数据文件和备份文件,基本表的大小为x;索引和临时空间的经验值为3-5 位,取上限5x;DBGEN产生的数据文件的大小为x;备份文件大小为x;总计需要的存储空间为8x。就是说SF=1,需要准备8 倍,即8 GB 存储空间,才能顺利地进行测试22 个查询语句 TPC- H 测试围绕22 个SELECT 语句展开,每个SELECT严格定义,遵守SQL- 92语法,并且不允许用户修改。标准中从4 个方面定义每个SELECT 语句,即商业问题、SELECT 的语法、参数和查询确认。这些SELECT 语句的复杂程度超过大多数实际的OLTP 应用,一个SELECT 执行时间少则几十秒,多则达15 小时以上,22 个查询语句执行一遍需数个小时。2 个更新操作为了逼真地模拟数据仓库的实际应用环境,在22 个查询执行的同时,还有一对更新操作RF1 和RF2 并发地执行。RF1向Order 表和Lineitem 表中插入原行数的0.1%的新行,模拟新销售业务的数据加入到数据库中;RF2 从Order 表和Lineitem表中删除等量与RF1 增加的数据,模拟旧的销售数据被淘汰。RF1 和RF2 的执行必须保证数据库的ACID 约束,并保持测试前后的数据库中的数据量不变。更新操作除输出成功或失败信息外,不产生其它输出信息3 个测试 TPC-H 测试分解为3 个子测试:数据装载测试、Power 测试和Throughput 测试。建立测试数据库的过程被称为装载数据,装载测试是为测试DBMS 装载数据的能力。装载测试是第一项测试,测试装载数据的时间,这项操作非常耗时。Power 测试是在数据装载测试完成后,数据库处于初始状态,未进行其它任何操作,特别是缓冲区还没有被测试数据库的数据,被称为raw查询。Power 测试要求22 个查询顺序执行1 遍,同时执行一对RF1 和RF2 操作。最后进行Throughput 测试,也是最核心和最复杂的测试,它更接近于实际应用环境,与Power 测试比对SUT 系统的压力有非常大的增加,有多个查询语句组,同时有一对RF1 和RF2 更新流。度量指标测试中测量的基础数据都与执行时间有关,这些时间又可分为:装载数据的每一步操作时间、每个查询执行时间和每个更新操作执行时间,由这些时间可计算出:数据装载时间、Power@Size、Throughput@Size、QphH@Size 和$/QphH@Size。装载数据时间装载数据的全过程有记时操作和不记时操作之分,记时操作必须测量所用时间,并计入到数据装载时间中。一般情况下,需要记时的操作有建表、插入数据和建立索引。查询和更新时间在Power 测试和Throughput 测试中所有查询和更新流的时间必须被测量和记录,每个查询时间的计时是从被提交查询的第一个字符开始到获得查询结果最后一个字符的时间为止。更新时间要分别测量RF1 和RF2 的时间,是从提交操作开始到完成操作结束的时间。Power@SizePower@Size 是Power 测试的结果,被定义为查询时间和更改时间的几何平均值的倒数,公式如下:
其中:Size 为数据规模;SF 为数据规模的比例因子;QI (i,0)为第 i个查询的时间,以秒为单位;R(I j,0)为 RFj更新的时间,以秒为单位。Throughput@Size Throughput@Size 是Throughput 测试的结果,被定义为所有查询执行时间平均值的倒数,公式如下:
TPC- H 标准的附录D,有两组ANSI C 语言源程序包,即DBGEN 和QGEN。DBGEN 用于产生被测试数据,用户通过命令行参数控制执行结果。QGEN 用于生产测试所需要的22 个SELECT、RF1 和RD2 两个更新操作。DBGEN 和QGEN 程序 TPC- H 标准的附录D,有两组ANSI C 语言源程序包,即DBGEN 和QGEN。DBGEN 用于产生被测试数据,用户通过命令行参数控制执行结果。QGEN 用于生产测试所需要的22 个SELECT、RF1 和RD2 两个更新操作。n 详细使用说明 http://www.geniiius.com/blog/generate-test-data-using-dbgen 你一步一步如何使用该工具来生成一个数据库,一套表的数据量足够大,能够证明性能优化的东西。1。 下载DBGEN下载,DBGEN从http://www.tpc.org/tpch/spec/tpch_2_14_3.zip和提取它。 在本指南中,我的zip文件解压到C:\ tpch_2_14_3 \
这是项目,我们需要建立可执行文件。2。 构建解决方案现在,打开C:\ \ DBGEN \ tpch.sln在Visual Studio。tpch_2_14_3 根据您的Visual Studio版本,你可能会面临着一个转换向导。 只需单击“完成”来执行转换。 所有你需要做的,是要建立完整的解决方案。 我有一些错误,因为一些锁定的文件,所以我必须手动删除所有文件从C:\ tpch_2_14_3 \ DBGEN \Debug文件夹之前,我可以编译解决方案。 结果是文件C:\ tpch_2_14_3 \ DBGEN \调试\ dbgen.exe。3。 生成数据使用dbgen.exe现在需要执行dbgen.exe。 如果我们执行该命令与-h,我们得到一些帮助:如果我们简单地运行dbgen.exe,默认情况下,生成1 GB的数据,分为8个不同的表(客户,国家,订单项的订单,零件,PARTSUPP,地区,供应商)。 -s参数指定一个比例因子,所以-S 10为我们提供了10GB,和100生成100GB的数据。 让我们尝试缺省的:哎呀,我们得到了一个错误! 这是为什么,我不知道,但我找到了解决办法很简单:将文件复制dbgen.exe,一个级别,所以它位于C:\ tpch_2_14_3 \ DBGEN文件夹,然后再试一次:-v给出详细的输出。 现在,它生成的文件为每个表。 根据您的系统的速度,这可能需要几分钟的时间。生成的文件将位于相同的目录中dbgen.exe。 生成的文件的列表是:生成tbl文件后需要建立表,将数据导入,在数据库中建立表与表之间的关系。在这里我将建表以及导入8个表的sql语句写出(仅适用于sqlserver2005其他数据库请具体参阅相关的产品的sql语句)使用方式:1》 创建数据库(名字自己定)2》 在此数据库下,新建查询,将下列语句拷贝到对话框中,点击执行,便可以生成数据库(表结构,表之间的主外键关系都有了)。SET ANSI_NULLSONGOSET QUOTED_IDENTIFIERONGOIF NOTEXISTS(SELECT*FROMsys.objectsWHEREobject_id=OBJECT_ID(N'.')ANDtypein(N'U'))BEGINCREATE TABLE .( NOT NULL, (25)NOTNULL, (152)NULL, CONSTRAINT PRIMARY KEYCLUSTERED( ASC)WITH(PAD_INDEX =OFF,STATISTICS_NORECOMPUTE =OFF, IGNORE_DUP_KEY=OFF,ALLOW_ROW_LOCKS =ON,ALLOW_PAGE_LOCKS =ON)ON ) ON ENDGOSET ANSI_NULLSONGOSET QUOTED_IDENTIFIERONGOIF NOTEXISTS(SELECT*FROMsys.objectsWHEREobject_id=OBJECT_ID(N'.')ANDtypein(N'U'))BEGINCREATE TABLE .( NOT NULL, (55)NOTNULL, (25)NOTNULL, (10)NOTNULL, (25)NOTNULL, NOT NULL, (10)NOTNULL, (15, 2)NOTNULL, (23)NOTNULL, CONSTRAINT PRIMARY KEYCLUSTERED( ASC)WITH(PAD_INDEX =OFF,STATISTICS_NORECOMPUTE =OFF,IGNORE_DUP_KEY=OFF,ALLOW_ROW_LOCKS =ON,ALLOW_PAGE_LOCKS =ON)ON ) ON ENDGOSET ANSI_NULLSONGOSET QUOTED_IDENTIFIERONGOIF NOTEXISTS(SELECT*FROMsys.objectsWHEREobject_id=OBJECT_ID(N'.')ANDtypein(N'U'))BEGINCREATE TABLE .( NOT NULL, NOT NULL, (1)NOTNULL, (15, 2)NOTNULL, NOT NULL, (15)NOTNULL, (15)NOTNULL, NOT NULL, (79)NOTNULL, CONSTRAINT PRIMARY KEYCLUSTERED( ASC)WITH(PAD_INDEX =OFF,STATISTICS_NORECOMPUTE =OFF,IGNORE_DUP_KEY=OFF,ALLOW_ROW_LOCKS =ON,ALLOW_PAGE_LOCKS =ON)ON ) ON ENDGOSET ANSI_NULLSONGOSET QUOTED_IDENTIFIERONGOIF NOTEXISTS(SELECT*FROMsys.objectsWHEREobject_id=OBJECT_ID(N'.')ANDtypein(N'U'))BEGINCREATE TABLE .( NOT NULL, NOT NULL, NOT NULL, NOT NULL, (15, 2)NOTNULL, (15, 2)NOTNULL, (15, 2)NOTNULL, (15, 2)NOTNULL, (1)NOTNULL, (1)NOTNULL, NOT NULL, NOTNULL, NOTNULL, (25)NOTNULL, (10)NOTNULL, (44)NOTNULL) ON ENDGOSET ANSI_NULLSONGOSET QUOTED_IDENTIFIERONGOIF NOTEXISTS(SELECT*FROMsys.objectsWHEREobject_id=OBJECT_ID(N'.')ANDtypein(N'U'))BEGINCREATE TABLE .( NOT NULL, (25)NOTNULL, (40)NOTNULL, NOT NULL, (15)NOTNULL, (15, 2)NOTNULL, (10)NOTNULL, (117)NOTNULL, CONSTRAINT PRIMARY KEYCLUSTERED( ASC)WITH(PAD_INDEX =OFF,STATISTICS_NORECOMPUTE =OFF,IGNORE_DUP_KEY=OFF,ALLOW_ROW_LOCKS =ON,ALLOW_PAGE_LOCKS =ON)ON ) ON ENDGOSET ANSI_NULLSONGOSET QUOTED_IDENTIFIERONGOIF NOTEXISTS(SELECT*FROMsys.objectsWHEREobject_id=OBJECT_ID(N'.')ANDtypein(N'U'))BEGINCREATE TABLE .( NOT NULL, (25)NOTNULL, (40)NOTNULL, NOT NULL, (15)NOTNULL, (15, 2)NOTNULL, (101)NOTNULL, CONSTRAINT PRIMARY KEYCLUSTERED( ASC)WITH(PAD_INDEX =OFF,STATISTICS_NORECOMPUTE =OFF,IGNORE_DUP_KEY=OFF,ALLOW_ROW_LOCKS =ON,ALLOW_PAGE_LOCKS =ON)ON ) ON ENDGOSET ANSI_NULLSONGOSET QUOTED_IDENTIFIERONGOIF NOTEXISTS(SELECT*FROMsys.objectsWHEREobject_id=OBJECT_ID(N'.')ANDtypein(N'U'))BEGINCREATE TABLE .( NOT NULL, (25)NOTNULL, NOT NULL, (152)NULL, CONSTRAINT PRIMARY KEYCLUSTERED( ASC)WITH(PAD_INDEX =OFF, STATISTICS_NORECOMPUTE =OFF, IGNORE_DUP_KEY=OFF,ALLOW_ROW_LOCKS =ON, ALLOW_PAGE_LOCKS =ON)ON ) ON ENDGOSET ANSI_NULLSONGOSET QUOTED_IDENTIFIERONGOIF NOTEXISTS(SELECT*FROMsys.objectsWHEREobject_id=OBJECT_ID(N'.')ANDtypein(N'U'))BEGINCREATE TABLE .( NOT NULL, NOT NULL, NOT NULL, (15, 2)NOTNULL, (199)NOTNULL, CONSTRAINT PRIMARY KEYCLUSTERED( ASC, ASC)WITH(PAD_INDEX =OFF,STATISTICS_NORECOMPUTE =OFF,IGNORE_DUP_KEY=OFF,ALLOW_ROW_LOCKS =ON,ALLOW_PAGE_LOCKS =ON)ON ) ON ENDGOIF NOTEXISTS(SELECT*FROMsys.foreign_keysWHEREobject_id=OBJECT_ID(N'.')ANDparent_object_id=OBJECT_ID(N'.'))ALTER TABLE . WITHCHECKADD CONSTRAINTFOREIGNKEY()REFERENCES .()GOALTER TABLE .CHECKCONSTRAINT GOIF NOTEXISTS(SELECT*FROMsys.foreign_keysWHEREobject_id=OBJECT_ID(N'.')ANDparent_object_id=OBJECT_ID(N'.'))ALTER TABLE . WITHNOCHECKADD CONSTRAINTFOREIGNKEY()REFERENCES .()GOALTER TABLE .CHECKCONSTRAINT GOIF NOTEXISTS(SELECT*FROMsys.foreign_keysWHEREobject_id=OBJECT_ID(N'.')ANDparent_object_id=OBJECT_ID(N'.'))ALTER TABLE . WITHNOCHECKADD CONSTRAINTFOREIGNKEY(,)REFERENCES .(,)GOALTER TABLE .CHECKCONSTRAINT GOIF NOTEXISTS(SELECT*FROMsys.foreign_keysWHEREobject_id=OBJECT_ID(N'.')ANDparent_object_id=OBJECT_ID(N'.'))ALTER TABLE . WITHCHECKADD CONSTRAINTFOREIGNKEY()REFERENCES .()GOALTER TABLE .CHECKCONSTRAINT GOIF NOTEXISTS(SELECT*FROMsys.foreign_keysWHEREobject_id=OBJECT_ID(N'.')ANDparent_object_id=OBJECT_ID(N'.'))ALTER TABLE . WITHCHECKADD CONSTRAINTFOREIGNKEY()REFERENCES .()GOALTER TABLE .CHECKCONSTRAINT GOIF NOTEXISTS(SELECT*FROMsys.foreign_keysWHEREobject_id=OBJECT_ID(N'.')ANDparent_object_id=OBJECT_ID(N'.'))ALTER TABLE . WITHCHECKADD CONSTRAINTFOREIGNKEY()REFERENCES .()GOALTER TABLE .CHECKCONSTRAINT GOIF NOTEXISTS(SELECT*FROMsys.foreign_keysWHEREobject_id=OBJECT_ID(N'.')ANDparent_object_id=OBJECT_ID(N'.'))ALTER TABLE . WITHCHECKADD CONSTRAINTFOREIGNKEY()REFERENCES .()GOALTER TABLE .CHECKCONSTRAINT GOIF NOTEXISTS(SELECT*FROMsys.foreign_keysWHEREobject_id=OBJECT_ID(N'.')ANDparent_object_id=OBJECT_ID(N'.'))ALTER TABLE . WITHCHECKADD CONSTRAINTFOREIGNKEY()REFERENCES .()GOALTER TABLE .CHECKCONSTRAINT 3》将dbgen生成的 8个表的.tbl文件导入到数据库中。1. GO2. BULK INSERT part FROM 'C:\tpch_2_14_3\dbgen\part.tbl' WITH (TABLOCK, DATAFILETYPE='char', CODEPAGE='raw', FIELDTERMINATOR = '|')3. BULK INSERT customer FROM 'C:\tpch_2_14_3\dbgen\customer.tbl' WITH (TABLOCK, DATAFILETYPE='char', CODEPAGE='raw', FIELDTERMINATOR = '|')4. BULK INSERT orders FROM 'C:\tpch_2_14_3\dbgen\orders.tbl' WITH (TABLOCK, DATAFILETYPE='char', CODEPAGE='raw', FIELDTERMINATOR = '|')5. BULK INSERT partsupp FROM 'C:\tpch_2_14_3\dbgen\partsupp.tbl' WITH (TABLOCK, DATAFILETYPE='char', CODEPAGE='raw', FIELDTERMINATOR = '|')6. BULK INSERT supplier FROM 'c:\tpch_2_14_3\dbgen\supplier.tbl' WITH (TABLOCK, DATAFILETYPE='char', CODEPAGE='raw', FIELDTERMINATOR = '|')7. BULK INSERT lineitem FROM 'C:\tpch_2_14_3\dbgen\lineitem.tbl' WITH (TABLOCK, DATAFILETYPE='char', CODEPAGE='raw', FIELDTERMINATOR = '|')8. BULK INSERT nation FROM 'C:\tpch_2_14_3\dbgen\nation.tbl' WITH (TABLOCK, DATAFILETYPE='char', CODEPAGE='raw', FIELDTERMINATOR = '|')9. BULK INSERT region FROM 'C:\tpch_2_14_3\dbgen\region.tbl' WITH (TABLOCK, DATAFILETYPE='char', CODEPAGE='raw', FIELDTERMINATOR = '|')
至此为止,dbgen生成的数据库全部内容已经导入到DBMS中。接下来,我们需要生成sql语句。这就需要用到qgen了.关于qgen的使用类似于dbgen首先我们打开22个查询语句中的第一个看到:
Qgen的其中一大作用就是将22条查询语句中的冒号替换为查询的数据,通过此方式来测试数据库的性能。我们首先用qgen来生成第一条查询语句,并将其保存到上级目录的saveSql中。运行qgen -d 1>..\saveSql\1.sql在saveSql文件夹中,可以看到已经有一个1.sql语句,打开看一下。select l_returnflag, l_linestatus, sum(l_quantity)as sum_qty, sum(l_extendedprice)as sum_base_price, sum(l_extendedprice*(1- l_discount))as sum_disc_price, sum(l_extendedprice*(1- l_discount)*(1+ l_tax))as sum_charge, avg(l_quantity)as avg_qty, avg(l_extendedprice)as avg_price, avg(l_discount)as avg_disc, count(*)as count_orderfrom lineitemwhere l_shipdate <= date '1998-12-01' - interval '90' day (3)group by l_returnflag, l_linestatusorder by l_returnflag, l_linestatus;set rowcount-1注意到 原来的“:”已经被替换为90.接下来的工作我们需要将保存的sql语句,利用自己开发的测试工具来进行测试。对于如何编写测试测试工具,我在这里不做介绍。给大家推荐几个国内较好论文,希望有所帮助。http://wenku.baidu.com/view/46a99819a76e58fafab0035d.htmlhttp://wenku.baidu.com/view/6df300aad1f34693daef3e18.html。http://wenku.baidu.com/view/b649f3c39ec3d5bbfd0a7454.html。TPC-H中文文档翻译(2.0.0.0版本)http://wenku.baidu.com/view/024e682cbd64783e09122bf4.html。
发帖前不看看格式吗?这个原创内容是翻译还是? 艹!一点也看不懂 看到这个我是醉了了....{:1_907:} 晕乎乎的感觉。高手的世界我不懂
页:
[1]