TPC-H數據導入MySQL教程


0. TPC-H是啥

TPC-H是TPC提供的一個benchmark,用來模擬一個現實中的商業應用,可以生成一堆虛構的數據,且自帶一些查詢,可以導入到各種數據庫中來模擬現實需求,檢查性能。

具體是怎樣的數據見:http://www.tpc.org/tpch/spec/tpch2.16.0.pdf

1. 獲取文件

首先到官網 http://www.tpc.org/tpch/ 在右邊的 DBGEN & Reference Data Set 下載到下面那個.zip,然后自己選一個路徑解壓過去。

2. 修改 makefile

在解壓的文件夾下面cd到dbgen下,找到makefile.suite。

~/tpch_2_16_1$ cd dbgen
~/tpch_2_16_1/dbgen$ vim makefile.suite

把103~112行左右改成這個樣子

CC      = 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 = TPCH
#

改動的地方分別是:

  • 設定C語言編譯器為gcc(如果你用的是其他的編譯器就改成其他對應名字)
  • DATABASE設為MYSQL(注意注釋里寫的提供的數據庫格式沒有mysql,所以等一下要自己寫一個格式,見步驟3)
  • MACHINE = LINUX 和 WORKLOAD = TPCH 就不用說啥意思了……

改好之后保存為makefile,這樣才好用make命令。

3. 修改tpcd.h

// 其實這一步好像沒什么用 = =
// 不過你上面把DATABASE設成了MYSQL的話就不要跳過這一步,不然編譯不了。 
// 或者上面那步也可以設成SQLSERVER這步就不用管了

之前說了官方的生成程序沒有mysql的格式,所以我們要自己寫一個,打開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

這樣就定義了一個MYSQL的腳本格式可以用了。

4. 生成dbgen

接下來make,生成數據生成腳本dbgen.

~/tpch_2_16_1/dbgen$ make

這個過程中會有一些關於數據類型的警告,一般可以無視。

make完dbgen目錄下之后就會多出很多.o(等到你所有事都干完確定這些沒有用了不想留着就make clean,或者直接整個文件夾刪掉……)和一個叫dbgen的文件

5. 生成tbl數據文件

接下來要用dbgen生成數據,一共會生成8個表(.tbl)。

查看README里面有命令行參數解說,這里我們在dbgen目錄下用

./dbgen -s 1

-s 1 表示生成1G的數據 (如果你之前曾經嘗試過生成數據,最好先make clean,再重新make,接着到這步加上-f覆蓋掉)

生成之后可以用head命令檢查一下tbl們,會看到每一行都有一些用“|”隔開的字段。

 

6. 修改初始化腳本使mySQL可用

壓縮包里自帶兩個腳本:

  • dss.ddl:用來建表
  • dss.ri:關聯表中primary key和foreign key。

不過這些腳本不能直接在mySQL里用(看README就知道人家根本沒考慮過mySQL……),要修改。

dss.ddl的開頭需要加上一些給MySQL建立數據庫連接用的指令。改完之后是這樣:

https://gist.github.com/joyeec9h3/9617329

dss.ri 的情況復雜一些,因為MySQL里添加外鍵要指明鍵的名字,所以每個加外鍵的指令都需要改。前面也有幾行MySQL不兼容的東西,改完之后是這樣:

https://gist.github.com/joyeec9h3/9617302

如果要直接用這兩個腳本請注意:

  1. dss.ddl開頭的tpch是數據庫的名字,你也可以換成其他名字,但如果改了,dss.ri里凡是提到“tpch”的地方也要改成對應的數據庫名字。
  2. 這兩個腳本用的表名和field名均和tpch文檔一致,但tpch自帶的測試貌似用了另外的表名。

以下可選,但本教程后面的步驟沒有考慮這步

鑒於tpch自帶的測試用的表名是小寫的,而dss.ddl里面的表名是大寫的,我們最好也改成小寫……

用vim打開dss.ddl,執行

:%s/TABLE\(.*\)/TABLE\L\1

就可以了。

如果你要事后改,就進到mySQL里,USE tpch,然后用類似於

alter table CUSTOMER rename to customer;

這樣的語句改就行了。嫌一個個打麻煩的話就寫腳本吧~

 

7. 建表

打開mysql,執行

mysql> \. ~/tpch_2_16_1/dbgen/dss.ddl

后面那部分是dss.ddl的路徑,要按照你的實際存放地址修改

然后可以用

mysql> SHOW DATABASES;

看到有一個叫tpch的數據庫,像這樣:

就說明建庫成功了。(記得打分號,我老是忘記打分號……)

再執行

mysql> USE tpch;
mysql> SHOW TABLES;

可以看到生成的8個表就說明建表成功,像這樣

 

下一步需要添加外鍵和主鍵,執行

mysql> \. ~/tpch_2_16_1/dbgen/dss.ri

同樣記得dss.ri的路徑要改成你的實際存放路徑。

如果想看看外鍵和主鍵是否添加成功,有沒有添加對,可以執行 SHOW CREATE TABLE 表名(覺得默認格式很礙眼可以試試看加上\G垂直打印),像這樣:

可以看到有哪些限制加進去了。

做完以上步驟之后光有一堆表和限制,里面是沒有數據的,需要從之前生成的.tbl里將實際的數據導入進來。

8. 寫個導入tbl文件的腳本

你也可以進到mysql然后寫一堆類似於

LOAD DATA LOCAL INFILE '/home/joyeecheung/tpch_2_16_1/dbgen/supplier.tbl' INTO TABLE SUPPLIER
FIELDS TERMINATED BY '|' LINES TERMINATED BY '|\n';

的東西,不過實在太龜毛了……所以還是寫一個bash腳本自動生成這些語句好了。

 

// 懶得運行腳本生成指令or需要添加外鍵主鍵的請往后跳一點直接看成品……

// 不懂bash的人可以看下面,懂的大牛看了這么弱的腳本請別來pia我……

dbgen目錄下新建一個load.sh(或者隨便什么名字),把這些東西復制進去

https://gist.github.com/joyeec9h3/9619766

以load.sh為名保存到dbgen目錄下,然后執行

sh load.sh

同目錄下就會生成一個loaddata.sql,里面是從8個tbl里導入數據的sql指令。

 

注意如果需要導入外鍵和主鍵,要根據各個表的依賴關系調整一下導入各個文件的順序。(其實就是拓撲排序口桀口桀……不過也就是把八個代碼塊調整一下順序而已,這么點工作量就不寫代碼了)

成品看這里,可以直接復制保存到dbgen目錄下進行下一步(要直接用記得替換成你的保存路徑)

https://gist.github.com/joyeec9h3/9619336

 

9. 執行腳本導入數據

在dbgen目錄下運行

mysql --local-infile -u root -p < loaddata.sql

記得要加那個 --local-infile,因為MySQL為了安全默認是把從外部文件導入數據的功能關掉的,要導入的話就必須在啟動MySQL的時候打開這個功能。

接下來可以喝杯茶等導入。如果你覺得它好像死在那里了,可以再開一個終端,登陸MySQL,用SHOW processlist;看看它在干嘛。

如果你好奇導入多少了,可以用SHOW TABLE STATUS FROM tpch; 看看目前每個表都導入了多少行,對照一下文檔里寫的1G數據量每個表總共會有幾行數據,心里就有譜了。

10. 檢查導入結果

按照前面的步驟,如果你不加foreign key和primary key關聯的話,導入還是挺快的……

我的本本CPU是i7-2670QM@2.20GHz,虛擬機分配了2個核和2G內存,日立的硬盤分了20G給它(現在一看貌似不夠用啊囧),大概7分鍾左右就能導入完的樣子。如果加了外鍵和主鍵速度會顯著降低,大約是60多分鍾,而且貌似越到后面速度越慢。

導入完了之后可以用

SHOW TABLE STATUS FROM tpch;

看看是不是都導入進去了,對照一下文檔的13頁,看看每個表行數有沒有差太遠,我測試是都導進去了,查詢結果如下:

mysql> SHOW TABLE STATUS FROM tpch\G;
*************************** 1. row ***************************
           Name: CUSTOMER
         Engine: InnoDB
        Version: 10
     Row_format: Compact
           Rows: 149842
 Avg_row_length: 192
    Data_length: 28884992
Max_data_length: 0
   Index_length: 3686400
      Data_free: 130023424
 Auto_increment: NULL
    Create_time: 2014-03-18 18:43:43
    Update_time: NULL
     Check_time: NULL
      Collation: latin1_swedish_ci
       Checksum: NULL
 Create_options: 
        Comment: 
*************************** 2. row ***************************
           Name: LINEITEM
         Engine: InnoDB
        Version: 10
     Row_format: Compact
           Rows: 6009452
 Avg_row_length: 147
    Data_length: 883949568
Max_data_length: 0
   Index_length: 218103808
      Data_free: 130023424
 Auto_increment: NULL
    Create_time: 2014-03-18 18:43:43
    Update_time: NULL
     Check_time: NULL
      Collation: latin1_swedish_ci
       Checksum: NULL
 Create_options: 
        Comment: 
*************************** 3. row ***************************
           Name: NATION
         Engine: InnoDB
        Version: 10
     Row_format: Compact
           Rows: 25
 Avg_row_length: 655
    Data_length: 16384
Max_data_length: 0
   Index_length: 16384
      Data_free: 130023424
 Auto_increment: NULL
    Create_time: 2014-03-18 18:43:43
    Update_time: NULL
     Check_time: NULL
      Collation: latin1_swedish_ci
       Checksum: NULL
 Create_options: 
        Comment: 
*************************** 4. row ***************************
           Name: ORDERS
         Engine: InnoDB
        Version: 10
     Row_format: Compact
           Rows: 1491770
 Avg_row_length: 131
    Data_length: 196804608
Max_data_length: 0
   Index_length: 39403520
      Data_free: 130023424
 Auto_increment: NULL
    Create_time: 2014-03-18 18:43:43
    Update_time: NULL
     Check_time: NULL
      Collation: latin1_swedish_ci
       Checksum: NULL
 Create_options: 
        Comment: 
*************************** 5. row ***************************
           Name: PART
         Engine: InnoDB
        Version: 10
     Row_format: Compact
           Rows: 200806
 Avg_row_length: 164
    Data_length: 33095680
Max_data_length: 0
   Index_length: 0
      Data_free: 130023424
 Auto_increment: NULL
    Create_time: 2014-03-18 18:43:43
    Update_time: NULL
     Check_time: NULL
      Collation: latin1_swedish_ci
       Checksum: NULL
 Create_options: 
        Comment: 
*************************** 6. row ***************************
           Name: PARTSUPP
         Engine: InnoDB
        Version: 10
     Row_format: Compact
           Rows: 778800
 Avg_row_length: 267
    Data_length: 208388096
Max_data_length: 0
   Index_length: 20496384
      Data_free: 130023424
 Auto_increment: NULL
    Create_time: 2014-03-18 18:43:43
    Update_time: NULL
     Check_time: NULL
      Collation: latin1_swedish_ci
       Checksum: NULL
 Create_options: 
        Comment: 
*************************** 7. row ***************************
           Name: REGION
         Engine: InnoDB
        Version: 10
     Row_format: Compact
           Rows: 5
 Avg_row_length: 3276
    Data_length: 16384
Max_data_length: 0
   Index_length: 0
      Data_free: 130023424
 Auto_increment: NULL
    Create_time: 2014-03-18 18:43:43
    Update_time: NULL
     Check_time: NULL
      Collation: latin1_swedish_ci
       Checksum: NULL
 Create_options: 
        Comment: 
*************************** 8. row ***************************
           Name: SUPPLIER
         Engine: InnoDB
        Version: 10
     Row_format: Compact
           Rows: 9594
 Avg_row_length: 274
    Data_length: 2637824
Max_data_length: 0
   Index_length: 278528
      Data_free: 130023424
 Auto_increment: NULL
    Create_time: 2014-03-18 18:43:43
    Update_time: NULL
     Check_time: NULL
      Collation: latin1_swedish_ci
       Checksum: NULL
 Create_options: 
        Comment: 
8 rows in set (0.81 sec)

 

還可以用 SELECT * FROM 表名 LIMIT 數量; 來從表抓幾個數據看:

 

參考鏈接

http://www.pilhokim.com/index.php?title=Project/EFIM/TPC-H&oldid=90509#Setup_MySQL

http://imysql.cn/2012/12/21/tpch-for-mysql-manual.html

http://my2iu.blogspot.com/2009/01/running-tpc-h-queries-on-mysql.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM