前言
这里采用了tpc-h一个数据库的数据量来进行查询计划的对比。并借助tpc-h中的22条查询语句进行执行计划分析。
mysql采用的是标准安装,TiDB采用的是单机测试版,这里的性能结果不能说明其性能差异
本文章主要目的是对比Mysql与TiDB在执行sql查询时的差异。
mysql版本5.7 TiDB版本v2.0.0-rc.4
准备阶段
数据导入TiDB后是缺少统计信息的:
SHOW STATS_META
可以手工进行统计信息的刷新
ANALYZE TABLE nation,region,part,supplier,partsupp,customer,orders,lineitem
刷新后再次查看SHOW STATS_META
首先选择Q17做为例子,进行查询
select
sum(l_extendedprice) / 7.0 asavg_yearlyfromlineitem,
partwherep_partkey=l_partkeyand p_brand = 'Brand#23'# 指定品牌。 BRAND=’Brand#MN’ ,M和N是两个字母,代表两个数值,相互独立,取值在1到5之间and p_container = 'MED BOX' # 指定包装类型。在TPC-H标准指定的范围内随机选择and l_quantity
0.2 * avg(l_quantity)fromlineitemwherel_partkey=p_partkey
);
表结构
CREATE TABLE IF NOT EXISTS part ( P_PARTKEY INTEGER NOT NULL,
P_NAMEVARCHAR(55) NOT NULL,
P_MFGRCHAR(25) NOT NULL,
P_BRANDCHAR(10) NOT NULL,
P_TYPEVARCHAR(25) NOT NULL,
P_SIZEINTEGER NOT NULL,
P_CONTAINERCHAR(10) NOT NULL,
P_RETAILPRICEDECIMAL(15,2) NOT NULL,
P_COMMENTVARCHAR(23) NOT NULL,PRIMARY KEY(P_PARTKEY));CREATE TABLE IF NOT EXISTS lineitem ( L_ORDERKEY INTEGER NOT NULL,
L_PARTKEYINTEGER NOT NULL,
L_SUPPKEYINTEGER NOT NULL,
L_LINENUMBERINTEGER NOT NULL,
L_QUANTITYDECIMAL(15,2) NOT NULL,
L_EXTENDEDPRICEDECIMAL(15,2) NOT NULL,
L_DISCOUNTDECIMAL(15,2) NOT NULL,
L_TAXDECIMAL(15,2) NOT NULL,
L_RETURNFLAGCHAR(1) NOT NULL,
L_LINESTATUSCHAR(1) NOT NULL,
L_SHIPDATE DATENOT NULL,
L_COMMITDATE DATENOT NULL,
L_RECEIPTDATE DATENOT NULL,
L_SHIPINSTRUCTCHAR(25) NOT NULL,
L_SHIPMODECHAR(10) NOT NULL,
L_COMMENTVARCHAR(44) NOT NULL,PRIMARY KEY(L_ORDERKEY,L_LINENUMBER),CONSTRAINT FOREIGN KEY LINEITEM_FK1 (L_ORDERKEY) referencesorders(O_ORDERKEY),CONSTRAINT FOREIGN KEY LINEITEM_FK2 (L_PARTKEY,L_SUPPKEY) references partsupp(PS_PARTKEY, PS_SUPPKEY));
part表是20万 ,而lineitem是600万,mysql在建立约束时,会自动创建一个索引LINEITEM_FK2(L_PARTKEY, L_SUPPKEY),而TiDB则不会
mysql的查询时间大概是1秒左右,TiDB的查询时间大概是30秒。
mysql的执行计划:
mysql首先对part表进行了查询,由于经过where的处理20万数据已经被过滤到几百条了。再与lineitem关联,最后再处理子查询。
查询过程中借用索引,所以大大加快了查询速度。
TiDB的执行计划