OceanBaseデータベースは、異なる種類の負荷が混在するシナリオにも対応可能です。ピアツーピアのノードで構成される分散アーキテクチャを採用しているため、高同時実行でスケーラブルなOLTPタスクを処理できます。それだけでなく、同じデータエンジン上でMPPアーキテクチャに基づいたOLAPの並列計算も実行できるため、2つの異なるデータストアを維持する必要がありません。
OceanBaseデータベースでは、大量のオンラインビジネスデータに対して直接並列分析を実行できるだけでなく、PDML (Parallel DML)機能によって、大量のデータを書き込む大規模トランザクションを並行処理で高速かつ安全に実行できます。これらはすべて、厳密なトランザクションの一貫性を保証した上で実現されます。
ここでは、TPC-Hテストを手動で実行し、OceanBaseデータベースのOperational OLAPシナリオにおける特徴と使用方法を説明します。TPC-Hは業界で一般的に使用される意思決定支援ビジネスのベンチマークで、大規模なデータセットに対する一連の複雑なクエリリクエストを通じて、データベースシステムの分析パフォーマンスと意思決定支援パフォーマンスを検証するものです。詳細については、TPC 組織公式ウェブサイトを参照してください。
説明
2021年5月20日、OceanBaseデータベースは1526万QphHのスコアでTPC-H世界記録を更新し、TPC-CとTPC-Hの両方の記録を更新した唯一のデータベースとなり、オンライントランザクションとリアルタイム分析の両方のビジネスシナリオを処理できるパフォーマンスを証明しました。詳細については、TPC-H Resultを参照してください。
TPC-Hテストの手動実行
TPC公式のTPC-Hツールに基づき、手動のステップバイステップでTPC-Hテストを実行する方法を以下に示します。手動テストは、OceanBaseデータベース、特にパラメータ設定について、より深く理解するのに役立ちます。
ステップ1:テストテナントの作成
説明
今回のテストにおけるOceanBaseクラスタ環境のデプロイモードは1:1:1です。
システムテナント(sysテナント)で以下のコマンドを実行して、テストテナントを作成します:
リソースユニット
mysql_boxを作成します。CREATE RESOURCE UNIT mysql_box MAX_CPU 28, MEMORY_SIZE '200G', MIN_IOPS 200000, MAX_IOPS 12800000, LOG_DISK_SIZE '300G';リソースプール
mysql_poolを作成します。CREATE RESOURCE POOL mysql_pool UNIT = 'mysql_box', UNIT_NUM = 1, ZONE_LIST = ('z1','z2','z3');MySQLモードのテナント
mysql_tenantを作成します。CREATE TENANT mysql_tenant RESOURCE_POOL_LIST = ('mysql_pool'), PRIMARY_ZONE = RANDOM, LOCALITY = 'F@z1,F@z2,F@z3' SET VARIABLES ob_compatibility_mode='mysql', ob_tcp_invited_nodes='%', secure_file_priv = "/";
ステップ2:環境最適化を行う
OceanBaseデータベースチューニング。
システムテナント(
sysテナント)で以下のステートメントを実行し、関連パラメータを設定してください。ALTER SYSTEM FLUSH PLAN CACHE GLOBAL; ALTER SYSTEM SET enable_sql_audit = false; SELECT sleep(5); ALTER SYSTEM SET enable_perf_event = false; ALTER SYSTEM SET syslog_level = 'PERF'; ALTER SYSTEM SET enable_record_trace_log = false; ALTER SYSTEM SET data_storage_warning_tolerance_time = '300s'; ALTER SYSTEM SET _data_storage_io_timeout = '600s'; ALTER SYSTEM SET trace_log_slow_query_watermark = '7d'; ALTER SYSTEM SET large_query_threshold = '0ms'; ALTER SYSTEM SET enable_syslog_recycle = 1; ALTER SYSTEM SET max_syslog_file_count = 300;テナントチューニング。
テストテナント(ユーザーテナント)において、以下のステートメントを実行し、関連パラメータを設定してください。
SET GLOBAL NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS'; SET GLOBAL NLS_TIMESTAMP_FORMAT = 'YYYY-MM-DD HH24:MI:SS.FF'; SET GLOBAL NLS_TIMESTAMP_TZ_FORMAT = 'YYYY-MM-DD HH24:MI:SS.FF TZR TZD'; SET GLOBAL ob_query_timeout = 10800000000; SET GLOBAL ob_trx_timeout = 10000000000; SET GLOBAL ob_sql_work_area_percentage = 50; ALTER SYSTEM SET default_table_store_format = 'column' ; ALTER SYSTEM SET ob_enable_batched_multi_statement = 'true'; ALTER SYSTEM SET _io_read_batch_size = '128k'; ALTER SYSTEM SET _io_read_redundant_limit_percentage = 50; SET GLOBAL parallel_degree_policy = AUTO; SET GLOBAL parallel_servers_target = 10000; SET GLOBAL collation_connection = utf8mb4_bin; SET GLOBAL collation_database = utf8mb4_bin; SET GLOBAL collation_server = utf8mb4_bin; SET GLOBAL autocommit = 1; ALTER SYSTEM SET ob_enable_batched_multi_statement = 'true';
ステップ3:TPC-Hツールのインストール
1.TPC-Hツールをダウンロードします。詳細については、TPC-Hツールのダウンロードページを参照してください。
ダウンロード完了後、ファイルを解凍し、TPC-Hの解凍済みディレクトリに移動します。
[wieck@localhost ~] $ unzip 7e965ead-8844-4efa-a275-34e35f8ab89b-tpc-h-tool.zip [wieck@localhost ~] $ cd TPC-H_Tools_v3.0.0Makefile.suiteをコピーします。[wieck@localhost TPC-H_Tools_v3.0.0] $ cd dbgen/ [wieck@localhost dbgen] $ cp Makefile.suite MakefileMakefileファイルのCC、DATABASE、MACHINE、WORKLOADなどのパラメータ定義を変更します。[wieck@localhost dbgen] $ vim MakefileCC = gcc # Current values for DATABASE are: INFORMIX, DB2, TDAT (Teradata) # SQLSERVER, SYBASE, ORACLE, VECTORWISE # Current values for MACHINE are: ATT, DOS, HP, IBM, ICL, MVS, # SGI, SUN, U2200, VMS, LINUX, WIN32 # Current values for WORKLOAD are: TPCH DATABASE= MYSQL MACHINE = LINUX WORKLOAD = TPCHtpcd.hファイルを修正し、新しいマクロ定義を追加します。[wieck@localhost dbgen] $ vim tpcd.h#ifdef MYSQL #define GEN_QUERY_PLAN "" #define START_TRAN "START TRANSACTION" #define END_TRAN "COMMIT" #define SET_OUTPUT "" #define SET_ROWCOUNT "limit %d;\n" #define SET_DBASE "use %s;\n" #endif
6.ファイルをコンパイルします。
make
結果は次のとおりです:
gcc -g -DDBNAME=\"dss\" -DLINUX -DMYSQL -DTPCH -DRNG_TEST -D_FILE_OFFSET_BITS=64 -c -o build.o build.c
gcc -g -DDBNAME=\"dss\" -DLINUX -DMYSQL -DTPCH -DRNG_TEST -D_FILE_OFFSET_BITS=64 -c -o driver.o driver.c
gcc -g -DDBNAME=\"dss\" -DLINUX -DMYSQL -DTPCH -DRNG_TEST -D_FILE_OFFSET_BITS=64 -c -o bm_utils.o bm_utils.c
gcc -g -DDBNAME=\"dss\" -DLINUX -DMYSQL -DTPCH -DRNG_TEST -D_FILE_OFFSET_BITS=64 -c -o rnd.o rnd.c
gcc -g -DDBNAME=\"dss\" -DLINUX -DMYSQL -DTPCH -DRNG_TEST -D_FILE_OFFSET_BITS=64 -c -o print.o print.c
gcc -g -DDBNAME=\"dss\" -DLINUX -DMYSQL -DTPCH -DRNG_TEST -D_FILE_OFFSET_BITS=64 -c -o load_stub.o load_stub.c
gcc -g -DDBNAME=\"dss\" -DLINUX -DMYSQL -DTPCH -DRNG_TEST -D_FILE_OFFSET_BITS=64 -c -o bcd2.o bcd2.c
gcc -g -DDBNAME=\"dss\" -DLINUX -DMYSQL -DTPCH -DRNG_TEST -D_FILE_OFFSET_BITS=64 -c -o speed_seed.o speed_seed.c
gcc -g -DDBNAME=\"dss\" -DLINUX -DMYSQL -DTPCH -DRNG_TEST -D_FILE_OFFSET_BITS=64 -c -o text.o text.c
gcc -g -DDBNAME=\"dss\" -DLINUX -DMYSQL -DTPCH -DRNG_TEST -D_FILE_OFFSET_BITS=64 -c -o permute.o permute.c
gcc -g -DDBNAME=\"dss\" -DLINUX -DMYSQL -DTPCH -DRNG_TEST -D_FILE_OFFSET_BITS=64 -c -o rng64.o rng64.c
gcc -g -DDBNAME=\"dss\" -DLINUX -DMYSQL -DTPCH -DRNG_TEST -D_FILE_OFFSET_BITS=64 -O -o dbgen build.o driver.o bm_utils.o rnd.o print.o load_stub.o bcd2.o speed_seed.o text.o permute.o rng64.o -lm
gcc -g -DDBNAME=\"dss\" -DLINUX -DMYSQL -DTPCH -DRNG_TEST -D_FILE_OFFSET_BITS=64 -c -o qgen.o qgen.c
gcc -g -DDBNAME=\"dss\" -DLINUX -DMYSQL -DTPCH -DRNG_TEST -D_FILE_OFFSET_BITS=64 -c -o varsub.o varsub.c
gcc -g -DDBNAME=\"dss\" -DLINUX -DMYSQL -DTPCH -DRNG_TEST -D_FILE_OFFSET_BITS=64 -O -o qgen build.o bm_utils.o qgen.o rnd.o varsub.o text.o bcd2.o permute.o speed_seed.o rng64.o -lm
後続の生成データ用のdbgenファイルと、SQL生成用のqgen、dists.dssファイルを生成します。
ステップ4:データの生成
実際の環境に応じて、TPC-Hの10GB、100GB、または1TBのデータを生成できます。この記事では、100GBのデータを生成する例を説明します。
./dbgen -s 100
mkdir tpch100
mv *.tbl tpch100
複数スレッドで1TBのデータを生成する場合、OceanBaseはダイレクトロードをサポートしており、複数のファイルのデータを同時にテーブルにインポートできます:
#!/bin/bash
SCALE_FACTOR=1000
CHUNK_COUNT=20
for ((i=1; i<=CHUNK_COUNT; i++))
do
CMD="./dbgen -s ${SCALE_FACTOR} -C ${CHUNK_COUNT} -S ${i} -vf"
$CMD &
done
wait
echo "All data generation tasks completed."
ステップ5:クエリSQLの生成
説明
このセクションの手順に従ってクエリSQLを生成し、調整することも、GitHubに掲載されているクエリSQLを直接使用することも可能です。GitHubのクエリSQLを使用する場合は、SQL文中のcpu_numを実際の並列数に修正する必要があります。
tpchに付属のツールを用いて生成します。手順は以下のとおりです:
dbgen/qgenとdbgen/dists.dssをmysql_sqlフォルダにコピーします。mysql_sqlフォルダにクエリSQLを生成するgen.shスクリプトを作成します。vim gen.sh#!/usr/bin/bash for i in {1..22} do ./qgen -d $i -s 100 > db"$i".sql done実際の同時実行数に基づいて、クエリSQLを変更します。
sysテナントで以下のコマンドを使用して、テナントで使用可能なCPUの総数を確認できます。select sum(max_cpu) from DBA_OB_UNITS;Q1を例にとると、修正後のSQL文は次のとおりです:SELECT /*+ parallel(96) */ ---parallelパラレル実行を追加 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_order FROM lineitem WHERE l_shipdate <= date '1998-12-01' - interval '90' day GROUP BY l_returnflag, l_linestatus ORDER BY l_returnflag, l_linestatus;
ステップ6:新規テーブル作成
100GBのデータを用いて、テーブル構造ファイル
create_tpch_mysql_table_part.ddlを作成します。drop tablegroup IF EXISTS tpch_tg_SF_TPC_USER_lineitem_order_group; drop tablegroup IF EXISTS tpch_tg_SF_TPC_USER_partsupp_part; create tablegroup tpch_tg_SF_TPC_USER_lineitem_order_group binding true partition by key 1 partitions 256; create tablegroup tpch_tg_SF_TPC_USER_partsupp_part binding true partition by key 1 partitions 256; DROP TABLE IF EXISTS LINEITEM; CREATE TABLE lineitem ( l_orderkey int(11) NOT NULL, l_partkey int(11) NOT NULL, l_suppkey int(11) NOT NULL, l_linenumber int(11) NOT NULL, l_quantity decimal(15,2) NOT NULL, l_extendedprice decimal(15,2) NOT NULL, l_discount decimal(15,2) NOT NULL, l_tax decimal(15,2) NOT NULL, l_returnflag char(1) DEFAULT NULL, l_linestatus char(1) DEFAULT NULL, l_shipdate date NOT NULL, l_commitdate date DEFAULT NULL, l_receiptdate date DEFAULT NULL, l_shipinstruct varchar(25) DEFAULT NULL, l_shipmode varchar(10) DEFAULT NULL, l_comment varchar(44) DEFAULT NULL, primary key(l_shipdate, l_orderkey, l_linenumber) )row_format = condensed tablegroup = tpch_tg_SF_TPC_USER_lineitem_order_group partition by key (l_orderkey) partitions 256 with column group(each column); alter table lineitem CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_bin; DROP TABLE IF EXISTS ORDERS; CREATE TABLE orders ( o_orderkey int(11) NOT NULL, o_custkey int(11) NOT NULL, o_orderstatus varchar(1) DEFAULT NULL, o_totalprice decimal(15,2) DEFAULT NULL, o_orderdate date NOT NULL, o_orderpriority varchar(15) DEFAULT NULL, o_clerk varchar(15) DEFAULT NULL, o_shippriority int(11) DEFAULT NULL, o_comment varchar(79) DEFAULT NULL, PRIMARY KEY (o_orderkey, o_orderdate) ) row_format = condensed tablegroup = tpch_tg_SF_TPC_USER_lineitem_order_group partition by key(o_orderkey) partitions 256 with column group(each column); alter table orders CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_bin; DROP TABLE IF EXISTS PARTSUPP; CREATE TABLE partsupp ( ps_partkey int(11) NOT NULL, ps_suppkey int(11) NOT NULL, ps_availqty int(11) DEFAULT NULL, ps_supplycost decimal(15,2) DEFAULT NULL, ps_comment varchar(199) DEFAULT NULL, PRIMARY KEY (ps_partkey, ps_suppkey)) row_format = condensed tablegroup tpch_tg_SF_TPC_USER_partsupp_part partition by key(ps_partkey) partitions 256 with column group(each column); alter table partsupp CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_bin; DROP TABLE IF EXISTS PART; CREATE TABLE part ( p_partkey int(11) NOT NULL, p_name varchar(55) DEFAULT NULL, p_mfgr varchar(25) DEFAULT NULL, p_brand varchar(10) DEFAULT NULL, p_type varchar(25) DEFAULT NULL, p_size int(11) DEFAULT NULL, p_container varchar(10) DEFAULT NULL, p_retailprice decimal(12,2) DEFAULT NULL, p_comment varchar(23) DEFAULT NULL, PRIMARY KEY (p_partkey)) row_format = condensed tablegroup tpch_tg_SF_TPC_USER_partsupp_part partition by key(p_partkey) partitions 256 with column group(each column); alter table part CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_bin; DROP TABLE IF EXISTS CUSTOMER; CREATE TABLE customer ( c_custkey int(11) NOT NULL, c_name varchar(25) DEFAULT NULL, c_address varchar(40) DEFAULT NULL, c_nationkey int(11) DEFAULT NULL, c_phone varchar(15) DEFAULT NULL, c_acctbal decimal(15,2) DEFAULT NULL, c_mktsegment char(10) DEFAULT NULL, c_comment varchar(117) DEFAULT NULL, PRIMARY KEY (c_custkey)) row_format = condensed partition by key(c_custkey) partitions 256 with column group(each column); alter table customer CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_bin; DROP TABLE IF EXISTS SUPPLIER; CREATE TABLE supplier ( s_suppkey int(11) NOT NULL, s_name varchar(25) DEFAULT NULL, s_address varchar(40) DEFAULT NULL, s_nationkey int(11) DEFAULT NULL, s_phone varchar(15) DEFAULT NULL, s_acctbal decimal(15,2) DEFAULT NULL, s_comment varchar(101) DEFAULT NULL, PRIMARY KEY (s_suppkey) ) row_format = condensed partition by key(s_suppkey) partitions 256 with column group(each column); alter table supplier CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_bin; DROP TABLE IF EXISTS NATION; CREATE TABLE nation ( n_nationkey int(11) NOT NULL, n_name varchar(25) DEFAULT NULL, n_regionkey int(11) DEFAULT NULL, n_comment varchar(152) DEFAULT NULL, PRIMARY KEY (n_nationkey) ) row_format = condensed with column group(each column); alter table nation CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_bin; DROP TABLE IF EXISTS REGION; CREATE TABLE region ( r_regionkey int(11) NOT NULL, r_name varchar(25) DEFAULT NULL, r_comment varchar(152) DEFAULT NULL, PRIMARY KEY (r_regionkey) ) row_format = condensed with column group(each column); alter table region CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_bin; CREATE VIEW revenue0 AS SELECT l_suppkey as supplier_no, SUM(l_extendedprice * ( 1 - l_discount )) as total_revenue FROM lineitem WHERE l_shipdate >= DATE '1996-01-01' AND l_shipdate < DATE '1996-04-01' GROUP BY l_suppkey;1TBのデータについて、テーブル構造ファイル
create_tpch_mysql_table_part_1000G.ddlを作成します。drop tablegroup IF EXISTS tpch_tg_SF_TPC_USER_lineitem_order_group_1000; drop tablegroup IF EXISTS tpch_tg_SF_TPC_USER_partsupp_part_1000; create tablegroup tpch_tg_SF_TPC_USER_lineitem_order_group_1000 binding true partition by key 1 partitions 256; create tablegroup tpch_tg_SF_TPC_USER_partsupp_part_1000 binding true partition by key 1 partitions 256; DROP TABLE IF EXISTS LINEITEM; CREATE TABLE lineitem ( l_orderkey bigint NOT NULL, l_partkey int(32) NOT NULL, l_suppkey int(32) NOT NULL, l_linenumber int(32) NOT NULL, l_quantity decimal(32,2) NOT NULL, l_extendedprice decimal(32,2) NOT NULL, l_discount decimal(15,2) NOT NULL, l_tax decimal(15,2) NOT NULL, l_returnflag varchar(64) DEFAULT NULL, l_linestatus varchar(64) DEFAULT NULL, l_shipdate date NOT NULL, l_commitdate date DEFAULT NULL, l_receiptdate date DEFAULT NULL, l_shipinstruct varchar(64) DEFAULT NULL, l_shipmode varchar(64) DEFAULT NULL, l_comment varchar(64) DEFAULT NULL, primary key(l_shipdate, l_orderkey, l_linenumber) )row_format = condensed tablegroup = tpch_tg_SF_TPC_USER_lineitem_order_group_1000 partition by key (l_orderkey) partitions 256 with column group(each column); alter table lineitem CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_bin; DROP TABLE IF EXISTS ORDERS; CREATE TABLE orders ( o_orderkey bigint NOT NULL, o_custkey int(32) NOT NULL, o_orderstatus varchar(64) DEFAULT NULL, o_totalprice decimal(15,2) DEFAULT NULL, o_orderdate date NOT NULL, o_orderpriority varchar(15) DEFAULT NULL, o_clerk varchar(15) DEFAULT NULL, o_shippriority int(32) DEFAULT NULL, o_comment varchar(128) DEFAULT NULL, PRIMARY KEY (o_orderkey, o_orderdate) ) row_format = condensed tablegroup = tpch_tg_SF_TPC_USER_lineitem_order_group_1000 partition by key(o_orderkey) partitions 256 with column group(each column); alter table orders CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_bin; DROP TABLE IF EXISTS PARTSUPP; CREATE TABLE partsupp ( ps_partkey int(11) NOT NULL, ps_suppkey int(11) NOT NULL, ps_availqty int(11) DEFAULT NULL, ps_supplycost decimal(15,2) DEFAULT NULL, ps_comment varchar(199) DEFAULT NULL, PRIMARY KEY (ps_partkey, ps_suppkey)) row_format = condensed tablegroup tpch_tg_SF_TPC_USER_partsupp_part_1000 partition by key(ps_partkey) partitions 256 with column group(each column); alter table partsupp CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_bin; DROP TABLE IF EXISTS PART; CREATE TABLE part ( p_partkey int(11) NOT NULL, p_name varchar(55) DEFAULT NULL, p_mfgr varchar(25) DEFAULT NULL, p_brand varchar(10) DEFAULT NULL, p_type varchar(25) DEFAULT NULL, p_size int(11) DEFAULT NULL, p_container varchar(10) DEFAULT NULL, p_retailprice decimal(12,2) DEFAULT NULL, p_comment varchar(23) DEFAULT NULL, PRIMARY KEY (p_partkey)) row_format = condensed tablegroup tpch_tg_SF_TPC_USER_partsupp_part_1000 partition by key(p_partkey) partitions 256 with column group(each column); alter table part CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_bin; DROP TABLE IF EXISTS CUSTOMER; CREATE TABLE customer ( c_custkey int(11) NOT NULL, c_name varchar(25) DEFAULT NULL, c_address varchar(40) DEFAULT NULL, c_nationkey int(11) DEFAULT NULL, c_phone varchar(15) DEFAULT NULL, c_acctbal decimal(15,2) DEFAULT NULL, c_mktsegment char(10) DEFAULT NULL, c_comment varchar(117) DEFAULT NULL, PRIMARY KEY (c_custkey)) row_format = condensed partition by key(c_custkey) partitions 256 with column group(each column); alter table customer CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_bin; DROP TABLE IF EXISTS SUPPLIER; CREATE TABLE supplier ( s_suppkey int(11) NOT NULL, s_name varchar(25) DEFAULT NULL, s_address varchar(40) DEFAULT NULL, s_nationkey int(11) DEFAULT NULL, s_phone varchar(15) DEFAULT NULL, s_acctbal decimal(15,2) DEFAULT NULL, s_comment varchar(101) DEFAULT NULL, PRIMARY KEY (s_suppkey) ) row_format = condensed partition by key(s_suppkey) partitions 256 with column group(each column); alter table supplier CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_bin; DROP TABLE IF EXISTS NATION; CREATE TABLE nation ( n_nationkey int(11) NOT NULL, n_name varchar(25) DEFAULT NULL, n_regionkey int(11) DEFAULT NULL, n_comment varchar(152) DEFAULT NULL, PRIMARY KEY (n_nationkey) ) row_format = condensed with column group(each column); alter table nation CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_bin; DROP TABLE IF EXISTS REGION; CREATE TABLE region ( r_regionkey int(11) NOT NULL, r_name varchar(25) DEFAULT NULL, r_comment varchar(152) DEFAULT NULL, PRIMARY KEY (r_regionkey) ) row_format = condensed with column group(each column); alter table region CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_bin; CREATE VIEW revenue0 AS SELECT l_suppkey as supplier_no, SUM(l_extendedprice * ( 1 - l_discount )) as total_revenue FROM lineitem WHERE l_shipdate >= DATE '1996-01-01' AND l_shipdate < DATE '1996-04-01' GROUP BY l_suppkey;
ステップ7:データの読み込み
上記の手順で生成されたデータとSQLを使用して、スクリプトを独自に作成できます。データの読み込み手順の例を以下に示します:
データの読み込みスクリプト
load_data.shを作成します。#!/bin/bash host='$host_ip' # 注意:任意のobserver(例:observer Aのサーバー)のIPアドレスを入力してください。データファイルも同一サーバーに配置することを推奨します port='$host_port' # observer Aのポート番号 user='$user' # ユーザー名 tenant='$tenant_name' # テナント名 password='$password' # パスワード database='$db_name' # データベース名 data_path='$data_file' # 注意:任意のobserver(例: observer A)のデータ生成手順で生成されたデータファイル .tblへのパスを入力してください function load_data { remote_user="$user" # データを格納するobserverノードのユーザー名 table_name=${1} if [[ ${password} == "" ]];then obclient_conn="obclient -h${host} -P${port} -u${user} -D${database} -A -c" else obclient_conn="obclient -h${host} -P${port} -u${user} -D${database} -p${password} -A -c" fi table_list=$(ssh "${remote_user}@${host}" "ls ${data_path}/${table_name}.tbl* 2>/dev/null") echo "$table_list" IFS=$'\n' read -d '' -r -a table_files <<< "$table_list" table_files_comma_separated=$(IFS=,; echo "${table_files[*]}") echo "${table_files_comma_separated}" echo `date "+[%Y-%m-%d %H:%M:%S]"` "----------------------${table_name} テーブルのデータファイルをインポートしています----------------------" # ダイレクトロード方式でデータをインポートします。必要に応じて、他の方法に変更することも可能です echo "load data /*+ parallel(80) direct(true,0) */ infile '${table_files_comma_separated}' into table ${table_name} fields terminated by '|';" | ${obclient_conn} } starttime=`date +%s%N` for table in "nation" "region" "customer" "lineitem" "orders" "partsupp" "part" "supplier" do load_data "${table}" done end_time=`date +%s%N` totaltime=`echo ${end_time} ${starttime} | awk '{printf "%0.2f\n", ($1 - $2) / 1000000000}'` echo `date "+[%Y-%m-%d %H:%M:%S]"` "load data cost ${totaltime}s"データの読み込み後、データのメジャーコンパクション(Major Compaction)と統計情報の集計が必要です。
メジャーコンパクション(Major Compaction)を実行します。
テストテナントで以下のステートメントを実行してメジャーコンパクションを行います。
ALTER SYSTEM MAJOR FREEZE;メジャーコンパクションが完了したかどうかを確認します。
sysテナントでメジャーコンパクションが完了したかどうかを確認できますSELECT dt.TENANT_NAME, cc.FROZEN_SCN, cc.LAST_SCN FROM oceanbase.DBA_OB_TENANTS dt, oceanbase.CDB_OB_MAJOR_COMPACTION cc WHERE dt.TENANT_ID = cc.TENANT_ID AND dt.TENANT_NAME = 'mysql_tenant';説明
すべての
FROZEN_SCNとLAST_SCNの値が等しい場合、メジャーコンパクションが完了したことを示します。統計情報の収集を実行します。
統計情報収集ファイル
analyze_table.sqlを作成します。call dbms_stats.gather_table_stats(NULL, 'part', degree=>128, granularity=>'AUTO', method_opt=>'FOR ALL COLUMNS SIZE 128'); call dbms_stats.gather_table_stats(NULL, 'lineitem', degree=>128, granularity=>'AUTO', method_opt=>'FOR ALL COLUMNS SIZE 128'); call dbms_stats.gather_table_stats(NULL, 'customer', degree=>128, granularity=>'AUTO', method_opt=>'FOR ALL COLUMNS SIZE 128'); call dbms_stats.gather_table_stats(NULL, 'orders', degree=>128, granularity=>'AUTO', method_opt=>'FOR ALL COLUMNS SIZE 128'); call dbms_stats.gather_table_stats(NULL, 'partsupp', degree=>128, granularity=>'AUTO', method_opt=>'FOR ALL COLUMNS SIZE 128'); call dbms_stats.gather_table_stats(NULL, 'supplier', degree=>128, granularity=>'AUTO', method_opt=>'FOR ALL COLUMNS SIZE 128');テストテナントにログインし、以下のステートメントを実行して統計情報を収集します:
source analyze_table.sql
ステップ8:テストを実行する
上記の手順で生成されたデータとSQLを使用して、スクリプトを独自に作成できます。テストサンプル操作の実行手順は以下のとおりです:
テストスクリプト
tpch.shを作成します。#!/bin/bash host='$host_ip' # 注意:任意のobserver(例:observer Aのサーバー)のIPアドレスを入力してください port='$host_port' # observer Aのポート番号 user='$user' # ユーザー名 tenant='$tenant_name' # テナント名 password='$password' # パスワード database='$db_name' # データベース名 if [[ ${password} == "" ]];then TPCH_TEST="obclient -h${host} -P${port} -u${user}@{$tenant} -D${database} -A -c" else TPCH_TEST="obclient -h${host} -P${port} -p${password} -u${user}@{$tenant} -D${database} -A -c" fi function clear_kvcache { if [[ ${password_sys} == "" ]];then obclient_sys="obclient -h${host} -P${port} -uroot@sys -Doceanbase -A -c" else obclient_sys="obclient -h${host} -P${port} -uroot@sys -Doceanbase -p${password_sys} -A -c" fi tenant_name=${user#*@} echo "alter system flush kvcache ;" | ${obclient_sys} echo "alter system flush kvcache tenant '${tenant_name}' cache 'user_row_cache';" | ${obclient_sys} sleep 3s } function do_explain { #実行計画 echo `date '+[%Y-%m-%d %H:%M:%S]'` "BEGIN EXPLAIN ALL TPCH PLAN" for i in {1..22} do sql_explain="source explain_mysql/${i}.sql" echo `date '+[%Y-%m-%d %H:%M:%S]'` "BEGIN EXPLAIN Q${i}:" echo ${sql_explain} | ${TPCH_TEST} | sed 's/\\n/\n/g' |tee explain_log/${i}.exp echo `date '+[%Y-%m-%d %H:%M:%S]'` "Q${i} END" done } function do_warmup { #warmup ウォームアップ totaltime=0 for i in {1..22} do starttime=`date +%s%N` echo `date '+[%Y-%m-%d %H:%M:%S]'` "BEGIN prewarm Q${i}" sql1="source mysql_sql/${i}.sql" echo ${sql1}| ${TPCH_TEST} > mysql_log/${i}_prewarm.log || ret=1 stoptime=`date +%s%N` costtime=`echo ${stoptime} ${starttime} | awk '{printf "%0.2f\n", ($1 - $2) / 1000000000}'` first_array[$i]=$(echo "scale=2; ${first_array[$i]} + $costtime" | bc) echo `date '+[%Y-%m-%d %H:%M:%S]'` "END,COST ${costtime}s" totaltime=`echo ${totaltime} ${costtime} | awk '{printf "%0.2f\n", ($1 + $2)}'` done echo "total cost:${totaltime}s" } function hot_run { #正式な実行 for j in {1..10} do totaltime=0 for i in {1..22} do starttime=`date +%s%N` echo `date '+[%Y-%m-%d %H:%M:%S]'` "BEGIN BEST Q${i} (hot run)" sql1="source mysql_sql/${i}.sql" echo ${sql1}| ${TPCH_TEST} > mysql_log/${i}.log || ret=1 stoptime=`date +%s%N` costtime=`echo ${stoptime} ${starttime} | awk '{printf "%0.2f\n", ($1 - $2) / 1000000000}'` hot_array[$i]=$(echo "scale=2; ${hot_array[$i]} + $costtime" | bc) echo `date '+[%Y-%m-%d %H:%M:%S]'` "END,COST ${costtime}s" totaltime=`echo ${totaltime} ${costtime} | awk '{printf "%0.2f\n", ($1 + $2)}'` done echo "total cost:${totaltime}s" done } function cold_run { #正式な実行 for j in {1..3} do totaltime=0 for i in {1..22} do clear_kvcache starttime=`date +%s%N` echo `date '+[%Y-%m-%d %H:%M:%S]'` "BEGIN BEST Q${i} (cold run)" sql1="source mysql_sql/${i}.sql" echo $sql1| $TPCH_TEST > mysql_log/${i}_cold.log || ret=1 stoptime=`date +%s%N` costtime=`echo $stoptime $starttime | awk '{printf "%0.2f\n", ($1 - $2) / 1000000000}'` cold_array[$i]=$(echo "scale=2; ${cold_array[$i]} + $costtime" | bc) echo `date '+[%Y-%m-%d %H:%M:%S]'` "END,COST ${costtime}s" totaltime=`echo ${totaltime} ${costtime} | awk '{printf "%0.2f\n", ($1 + $2)}'` done echo "total cost:${totaltime}s" done } do_explain do_warmup hot_run cold_runテストスクリプトを実行します。
sh tpch.sh
FAQ
データのインポートに失敗しました。エラーメッセージは以下のとおりです:
ERROR 1017 (HY000) at line 1: File not existtblファイルは、接続先のOceanBaseデータベースがあるマシンのディレクトリに配置する必要があります。データの読み込みはローカルインポートでなければならないためです。データ参照エラー。エラーメッセージは以下のとおりです:
ERROR 4624 (HY000):No memory or reach tenant memory limitメモリ不足です。テナントメモリの増分を推奨します。
データのインポートエラーが発生しました。エラーメッセージは以下のとおりです:
ERROR 1227 (42501) at line 1: Access deniedユーザーにアクセス権限を付与する必要があります。以下のコマンドを実行して、権限を付与します:
grant file on *.* to tpch_100g_part;
Operational OLAPの手動エクスペリエンス
上記の手順により、TPCHのテスト環境が構築されました。次に、手動でOceanBaseデータベースのOLAPにおけるパフォーマンスと特性を確認してみましょう。 まず、OBClientを使用してデータベースにログインします。OBClientがインストールされていない場合は、mysqlクライアントを使用することも可能です。
obclient -h127.0.0.1 -P2881 -uroot@test -Dtest -A -p -c
開始前に、OceanBaseクラスタとテナントの設定に基づいて、並列度を設定する必要があります。具体的には、テナントの現在のCPUコア数の2倍を超えない値を設定することを推奨します。例えば、テナントのCPU最大構成が8の場合、並列度を16に設定することを推奨します。
MySQL [test]> SET GLOBAL parallel_servers_target=16;
Query OK, 0 rows affected
MySQL [test]> SET GLOBAL parallel_max_servers=16;
Query OK, 0 rows affected
OceanBaseデータベースは、ほとんどのMySQLの内部ビューと互換性があります。以下のクエリで、現在の環境におけるテーブルのサイズを確認できます。
MySQL [test]> SELECT table_name, table_rows, CONCAT(ROUND(data_length/(1024*1024*1024),2),' GB') table_size FROM information_schema.TABLES WHERE table_schema = 'test' order by table_rows desc;
+------------+------------+------------+
| table_name | table_rows | table_size |
+------------+------------+------------+
| lineitem | 6001215 | 0.37 GB |
| orders | 1500000 | 0.08 GB |
| partsupp | 800000 | 0.04 GB |
| part | 200000 | 0.01 GB |
| customer | 150000 | 0.01 GB |
| supplier | 10000 | 0.00 GB |
| nation | 25 | 0.00 GB |
| region | 5 | 0.00 GB |
+------------+------------+------------+
8 rows in set
TPC-HテストのQ1を使用して、OceanBaseデータベースのクエリのパフォーマンスを検証します。Q1クエリは、最大のlineitemテーブルについて、指定期間内における各種商品の価格、割引率、出荷量、数量などの情報を集計したり分析したりします。このクエリは、テーブル全体のデータを読み取り、パーティション化、ソート、集計などの計算を実行します。
並行クエリを無効にする
まず、デフォルトでパラレル処理を無効にした状態でこのクエリを実行します:
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_order
from
lineitem
where
l_shipdate <= date '1998-12-01' - interval '90' day
group by
l_returnflag,
l_linestatus
order by
l_returnflag,
l_linestatus;
このテスト環境における実行結果は次のとおりです:
+--------------+--------------+----------+----------------+----------------+--------------+---------+------------+----------+-------------+
| l_returnflag | l_linestatus | sum_qty | sum_base_price | sum_disc_price | sum_charge | avg_qty | avg_price | avg_disc | count_order |
+--------------+--------------+----------+----------------+----------------+--------------+---------+------------+----------+-------------+
| A | F | 37734107 | 56586577106 | 56586577106 | 56586577106 | 25.5220 | 38273.1451 | 0.0000 | 1478493 |
| N | F | 991417 | 1487505208 | 1487505208 | 1487505208 | 25.5165 | 38284.4806 | 0.0000 | 38854 |
| N | O | 74476040 | 111701776272 | 111701776272 | 111701776272 | 25.5022 | 38249.1339 | 0.0000 | 2920374 |
| R | F | 37719753 | 56568064200 | 56568064200 | 56568064200 | 25.5058 | 38250.8701 | 0.0000 | 1478870 |
+--------------+--------------+----------+----------------+----------------+--------------+---------+------------+----------+-------------+
4 rows in set (6.791 sec)
パラレルクエリを有効にする
OceanBaseデータベースのOperational OLAP機能は、単一のデータセットと実行エンジンに基づいており、異種データの同期およびメンテナンスは不要です。次に、parallelHintを追加して、並列度8でこのステートメントを再度実行します:
select /*+parallel(8) */
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_order
from
lineitem
where
l_shipdate <= date '1998-12-01' - interval '90' day
group by
l_returnflag,
l_linestatus
order by
l_returnflag,
l_linestatus;
同一環境とデータセットにおいて、実行結果は次のとおりです:
+--------------+--------------+----------+----------------+----------------+--------------+---------+------------+----------+-------------+
| l_returnflag | l_linestatus | sum_qty | sum_base_price | sum_disc_price | sum_charge | avg_qty | avg_price | avg_disc | count_order |
+--------------+--------------+----------+----------------+----------------+--------------+---------+------------+----------+-------------+
| A | F | 37734107 | 56586577106 | 56586577106 | 56586577106 | 25.5220 | 38273.1451 | 0.0000 | 1478493 |
| N | F | 991417 | 1487505208 | 1487505208 | 1487505208 | 25.5165 | 38284.4806 | 0.0000 | 38854 |
| N | O | 74476040 | 111701776272 | 111701776272 | 111701776272 | 25.5022 | 38249.1339 | 0.0000 | 2920374 |
| R | F | 37719753 | 56568064200 | 56568064200 | 56568064200 | 25.5058 | 38250.8701 | 0.0000 | 1478870 |
+--------------+--------------+----------+----------------+----------------+--------------+---------+------------+----------+-------------+
4 rows in set (1.197 sec)
デフォルトの非パラレル実行時間と比較して、パラレルクエリの実行速度は約6倍向上しました。EXPLAINコマンドで実行計画を確認すると、並列度も表示されていることがわかります(18行目、演算子1、dop=8):
===============================================================
|ID|OPERATOR |NAME |EST. ROWS|COST |
---------------------------------------------------------------
|0 |PX COORDINATOR MERGE SORT | |6 |13507125|
|1 | EXCHANGE OUT DISTR |:EX10001|6 |13507124|
|2 | SORT | |6 |13507124|
|3 | HASH GROUP BY | |6 |13507107|
|4 | EXCHANGE IN DISTR | |6 |8379337 |
|5 | EXCHANGE OUT DISTR (HASH)|:EX10000|6 |8379335 |
|6 | HASH GROUP BY | |6 |8379335 |
|7 | PX BLOCK ITERATOR | |5939712 |3251565 |
|8 | TABLE SCAN |lineitem|5939712 |3251565 |
===============================================================
Outputs & filters:
-------------------------------------
0 - output([lineitem.l_returnflag], [lineitem.l_linestatus], [T_FUN_SUM(T_FUN_SUM(lineitem.l_quantity))], [T_FUN_SUM(T_FUN_SUM(lineitem.l_extendedprice))], [T_FUN_SUM(T_FUN_SUM(lineitem.l_extendedprice * 1 - lineitem.l_discount))], [T_FUN_SUM(T_FUN_SUM(lineitem.l_extendedprice * 1 - lineitem.l_discount * 1 + lineitem.l_tax))], [T_FUN_SUM(T_FUN_SUM(lineitem.l_quantity)) / cast(T_FUN_COUNT_SUM(T_FUN_COUNT(lineitem.l_quantity)), DECIMAL(20, 0))], [T_FUN_SUM(T_FUN_SUM(lineitem.l_extendedprice)) / cast(T_FUN_COUNT_SUM(T_FUN_COUNT(lineitem.l_extendedprice)), DECIMAL(20, 0))], [T_FUN_SUM(T_FUN_SUM(lineitem.l_discount)) / cast(T_FUN_COUNT_SUM(T_FUN_COUNT(lineitem.l_discount)), DECIMAL(20, 0))], [T_FUN_COUNT_SUM(T_FUN_COUNT(*))]), filter(nil), sort_keys([lineitem.l_returnflag, ASC], [lineitem.l_linestatus, ASC])
1 - output([lineitem.l_returnflag], [lineitem.l_linestatus], [T_FUN_SUM(T_FUN_SUM(lineitem.l_quantity))], [T_FUN_SUM(T_FUN_SUM(lineitem.l_extendedprice))], [T_FUN_SUM(T_FUN_SUM(lineitem.l_extendedprice * 1 - lineitem.l_discount))], [T_FUN_SUM(T_FUN_SUM(lineitem.l_extendedprice * 1 - lineitem.l_discount * 1 + lineitem.l_tax))], [T_FUN_COUNT_SUM(T_FUN_COUNT(*))], [T_FUN_SUM(T_FUN_SUM(lineitem.l_quantity)) / cast(T_FUN_COUNT_SUM(T_FUN_COUNT(lineitem.l_quantity)), DECIMAL(20, 0))], [T_FUN_SUM(T_FUN_SUM(lineitem.l_extendedprice)) / cast(T_FUN_COUNT_SUM(T_FUN_COUNT(lineitem.l_extendedprice)), DECIMAL(20, 0))], [T_FUN_SUM(T_FUN_SUM(lineitem.l_discount)) / cast(T_FUN_COUNT_SUM(T_FUN_COUNT(lineitem.l_discount)), DECIMAL(20, 0))]), filter(nil), dop=8
2 - output([lineitem.l_returnflag], [lineitem.l_linestatus], [T_FUN_SUM(T_FUN_SUM(lineitem.l_quantity))], [T_FUN_SUM(T_FUN_SUM(lineitem.l_extendedprice))], [T_FUN_SUM(T_FUN_SUM(lineitem.l_extendedprice * 1 - lineitem.l_discount))], [T_FUN_SUM(T_FUN_SUM(lineitem.l_extendedprice * 1 - lineitem.l_discount * 1 + lineitem.l_tax))], [T_FUN_COUNT_SUM(T_FUN_COUNT(*))], [T_FUN_SUM(T_FUN_SUM(lineitem.l_quantity)) / cast(T_FUN_COUNT_SUM(T_FUN_COUNT(lineitem.l_quantity)), DECIMAL(20, 0))], [T_FUN_SUM(T_FUN_SUM(lineitem.l_extendedprice)) / cast(T_FUN_COUNT_SUM(T_FUN_COUNT(lineitem.l_extendedprice)), DECIMAL(20, 0))], [T_FUN_SUM(T_FUN_SUM(lineitem.l_discount)) / cast(T_FUN_COUNT_SUM(T_FUN_COUNT(lineitem.l_discount)), DECIMAL(20, 0))]), filter(nil), sort_keys([lineitem.l_returnflag, ASC], [lineitem.l_linestatus, ASC])
3 - output([lineitem.l_returnflag], [lineitem.l_linestatus], [T_FUN_SUM(T_FUN_SUM(lineitem.l_quantity))], [T_FUN_SUM(T_FUN_SUM(lineitem.l_extendedprice))], [T_FUN_SUM(T_FUN_SUM(lineitem.l_extendedprice * 1 - lineitem.l_discount))], [T_FUN_SUM(T_FUN_SUM(lineitem.l_extendedprice * 1 - lineitem.l_discount * 1 + lineitem.l_tax))], [T_FUN_COUNT_SUM(T_FUN_COUNT(lineitem.l_quantity))], [T_FUN_COUNT_SUM(T_FUN_COUNT(lineitem.l_extendedprice))], [T_FUN_SUM(T_FUN_SUM(lineitem.l_discount))], [T_FUN_COUNT_SUM(T_FUN_COUNT(lineitem.l_discount))], [T_FUN_COUNT_SUM(T_FUN_COUNT(*))]), filter(nil),
group([lineitem.l_returnflag], [lineitem.l_linestatus]), agg_func([T_FUN_SUM(T_FUN_SUM(lineitem.l_quantity))], [T_FUN_SUM(T_FUN_SUM(lineitem.l_extendedprice))], [T_FUN_SUM(T_FUN_SUM(lineitem.l_extendedprice * 1 - lineitem.l_discount))], [T_FUN_SUM(T_FUN_SUM(lineitem.l_extendedprice * 1 - lineitem.l_discount * 1 + lineitem.l_tax))], [T_FUN_COUNT_SUM(T_FUN_COUNT(*))], [T_FUN_COUNT_SUM(T_FUN_COUNT(lineitem.l_quantity))], [T_FUN_COUNT_SUM(T_FUN_COUNT(lineitem.l_extendedprice))], [T_FUN_SUM(T_FUN_SUM(lineitem.l_discount))], [T_FUN_COUNT_SUM(T_FUN_COUNT(lineitem.l_discount))])
4 - output([lineitem.l_returnflag], [lineitem.l_linestatus], [T_FUN_SUM(lineitem.l_quantity)], [T_FUN_SUM(lineitem.l_extendedprice)], [T_FUN_SUM(lineitem.l_extendedprice * 1 - lineitem.l_discount)], [T_FUN_SUM(lineitem.l_extendedprice * 1 - lineitem.l_discount * 1 + lineitem.l_tax)], [T_FUN_COUNT(lineitem.l_quantity)], [T_FUN_COUNT(lineitem.l_extendedprice)], [T_FUN_SUM(lineitem.l_discount)], [T_FUN_COUNT(lineitem.l_discount)], [T_FUN_COUNT(*)]), filter(nil)
5 - (#keys=2, [lineitem.l_returnflag], [lineitem.l_linestatus]), output([lineitem.l_returnflag], [lineitem.l_linestatus], [T_FUN_SUM(lineitem.l_quantity)], [T_FUN_SUM(lineitem.l_extendedprice)], [T_FUN_SUM(lineitem.l_extendedprice * 1 - lineitem.l_discount)], [T_FUN_SUM(lineitem.l_extendedprice * 1 - lineitem.l_discount * 1 + lineitem.l_tax)], [T_FUN_COUNT(lineitem.l_quantity)], [T_FUN_COUNT(lineitem.l_extendedprice)], [T_FUN_SUM(lineitem.l_discount)], [T_FUN_COUNT(lineitem.l_discount)], [T_FUN_COUNT(*)]), filter(nil), dop=8
6 - output([lineitem.l_returnflag], [lineitem.l_linestatus], [T_FUN_SUM(lineitem.l_quantity)], [T_FUN_SUM(lineitem.l_extendedprice)], [T_FUN_SUM(lineitem.l_extendedprice * 1 - lineitem.l_discount)], [T_FUN_SUM(lineitem.l_extendedprice * 1 - lineitem.l_discount * 1 + lineitem.l_tax)], [T_FUN_COUNT(lineitem.l_quantity)], [T_FUN_COUNT(lineitem.l_extendedprice)], [T_FUN_SUM(lineitem.l_discount)], [T_FUN_COUNT(lineitem.l_discount)], [T_FUN_COUNT(*)]), filter(nil),
group([lineitem.l_returnflag], [lineitem.l_linestatus]), agg_func([T_FUN_SUM(lineitem.l_quantity)], [T_FUN_SUM(lineitem.l_extendedprice)], [T_FUN_SUM(lineitem.l_extendedprice * 1 - lineitem.l_discount)], [T_FUN_SUM(lineitem.l_extendedprice * 1 - lineitem.l_discount * 1 + lineitem.l_tax)], [T_FUN_COUNT(*)], [T_FUN_COUNT(lineitem.l_quantity)], [T_FUN_COUNT(lineitem.l_extendedprice)], [T_FUN_SUM(lineitem.l_discount)], [T_FUN_COUNT(lineitem.l_discount)])
7 - output([lineitem.l_returnflag], [lineitem.l_linestatus], [lineitem.l_quantity], [lineitem.l_extendedprice], [lineitem.l_discount], [lineitem.l_extendedprice * 1 - lineitem.l_discount], [lineitem.l_extendedprice * 1 - lineitem.l_discount * 1 + lineitem.l_tax]), filter(nil)
8 - output([lineitem.l_returnflag], [lineitem.l_linestatus], [lineitem.l_quantity], [lineitem.l_extendedprice], [lineitem.l_discount], [lineitem.l_extendedprice * 1 - lineitem.l_discount], [lineitem.l_extendedprice * 1 - lineitem.l_discount * 1 + lineitem.l_tax]), filter([lineitem.l_shipdate <= ?]),
access([lineitem.l_shipdate], [lineitem.l_returnflag], [lineitem.l_linestatus], [lineitem.l_quantity], [lineitem.l_extendedprice], [lineitem.l_discount], [lineitem.l_tax]), partitions(p[0-15])
本記事の例では単一ノード環境でのデプロイを使用しています。特筆すべき点として、OceanBaseデータベースにおけるパラレル実行フレームワークの最大の特徴は、大量データの分析クエリをマルチノードでパラレル実行できる点です。例えば、1 億行以上のデータを含むテーブルが複数の OceanBaseデータベースノードに分散している場合、分析クエリを実行すると、OceanBaseデータベースの分散実行フレームワークは分散パラレル実行計画を生成し、複数のノードのリソースを利用して分析を実行します。そのため拡張性に優れており、パラレル処理の設定は SQL、セッション、テーブルの複数の次元で設定可能です。
obdツールを用いたTPC-Hテストの自動実行
適用対象
この内容はOceanBaseデータベースCommunity Editionのみに適用されます。OceanBaseデータベースEnterprise Editionは、現在obdの使用をサポートしていません。
TPC-Hテストでは、TPC公式サイト提供のデータセット生成ツールを参照するほかに、obdを使用してデータセットの生成、テーブル作成、データインポートを簡単に行い、22個のSQLを自動実行することもできます。
obdを使用してTPC-Hテストを実行する前に、OceanBaseとobdがデプロイ済みのノードにobtpchコンポーネントをインストールしておく必要があります。
sudo yum install obtpch
完了後、以下のコマンドを実行することで、データセットサイズ1GBのTPC-Hテストを開始できます。このプロセスには、データセットの生成、schemaのインポート、およびテストの自動実行が含まれます。本記事では、テスト環境のデプロイがOceanBaseデータベースのクイックスタートの手順と同一であることを前提とします。クラスタ名、パスワード、インストールディレクトリなどに相違点がある場合は、実際の状況に応じて調整してください。
注意
容量不足によるシステム異常を防ぐため、データセットファイルの配置に必要なディスク容量を確保してください。
この例では、/tmpディレクトリを使用してテストを行います。
cd /tmp
obd test tpch obtest --tenant=test -s 1 --password='******' --remote-tbl-dir=/tmp/tpch1
上記のコマンドを実行後、obdの実行が始まり、実行プロセス中の各ステップを確認できます:


データインポート完了後、obd は自動的に22個のSQLを実行し、各SQLの実行時間と合計実行時間を表示します。