PG-Stromを使ってみる

# はじめに
ゲームしないAIやらない人にとってのGPUのアドバンテージってなんやに引リツされた、SQLが早くなるというのをTwitter(現X)で見た。
HeteroDB社が開発しているPostgreSQLの処理を早くするというソフトウェア、PG-Stromだそうで。
面白そうだからやってみようの巻。

# 環境
- CPU: AMD Ryzen Threadripper 1950X
- RAM: DDR4 32GB
- GPU: NVIDIA Quadro RTX 4000
- SSD: Patriot Viper 256GB
- OS : AlmaLinux 9.5

:::note info
ハードウェア選定の注意点
GPUとSSDは条件がある。
- GPU
    - Compute Capabilityが6.0以降のモデル
        - PG-Stromの条件。
    - [ここ](https://developer.nvidia.com/cuda-gpus)に載っているGPUモデル
        - 理由:当初RTX 4070 Superでやっていたが、うまく動かなかった。
    - GPUDirect Storage(以降GDS)に対応している
        - 最近のは対応してそう。
- SSD
    - NVMeであること
        - GDSの美味しいところ。
:::

# 構築
公式サイトに沿う。(全て書くのが面倒(ｹﾞﾌﾝｹﾞﾌﾝ
公式サイトとは異なる点を書き出す。
- MOFEDドライバのインストール
    - インストールスクリプト実行時のオプション
        - `./mlnxofedinstall --with-nvmf --with-nfsrdma --enable-gds --add-kernel-support`
        - `--enable-gds`オプションをつけないと、サーバ再起動時にGDSが使えない。(なんで)
- OSのリソース制限の拡張
    - `/usr/lib/systemd/system/postgresql-16.service.d/pg_strom.conf`
    - 公式サイトでは/etc配下だが、実際は/usr配下だった。OSによる？

# 実験
計測してみよう。

## テーブル
すごく適当。
なんかのサービスの登録管理みたいな。
インデックス張っているのといないのと2種類作った。
```
=# CREATE TABLE test_table_user (number SERIAL, name TEXT NOT NULL, uniqueid TEXT NOT NULL);
=# CREATE TABLE test_table_user_info (uniqueid TEXT NOT NULL, location TEXT NOT NULL, sex TEXT NOT NULL, age SMALLINT NOT NULL);
```
レコードはPythonで2000万件ほど突っ込んだ。

## 計測SQL
- WHERE句
    - `EXPLAIN ANALYZE SELECT * FROM test_table_user_info WHERE sex = 'Female';`
- GROUOP BY句
    - `EXPLAIN ANALYZE SELECT location, AVG(age) FROM test_table_user_info GROUP BY location;`
- JOIN句
    - `EXPLAIN ANALYZE SELECT * FROM test_table_user JOIN test_table_user_info ON test_table_user.uniqueid = test_table_user_info.uniqueid;`
- 複合
    - `EXPLAIN ANALYZE SELECT location, AVG(age) FROM test_table_user JOIN test_table_user_info ON test_table_user.uniqueid = test_table_user_info.uniqueid WHERE sex = 'Male' GROUP BY location;`
- おまけ(重複抽出)
    - `EXPLAIN ANALYZE SELECT uniqueid FROM test_table_user GROUP BY uniqueid HAVING COUNT(uniqueid) > 1;`

データベース初心者なのでツッコミどころ満載だと思う。生暖かい目で見ていてほしい。()

# 実験結果
### WHERE句
<table>
  <thead>
    <tr>
      <td></td>
      <th>indexなし[ms]</th>
      <th>indexあり[ms]</th>
      <th>indexによる速度向上率[%]</th>
    </tr>
  </thead>
  <tr>
    <td>CPU</td>
    <td>1806</td>
    <td>1244</td>
    <td>145</td>
  </tr>
  <tr>
    <td>PG-Strom</td>
    <td>1202</td>
    <td>1094</td>
    <td>109</td>
  </tr>
  <tr>
    <td>PG-Stromによる速度向上率[%]</td>
    <td>150</td>
    <td>114</td>
    <td></td>
  </tr>
</table>

### GROUP BY句
<table>
  <thead>
    <tr>
      <td></td>
      <th>indexなし[ms]</th>
      <th>indexあり[ms]</th>
      <th>indexによる速度向上率[%]</th>
    </tr>
  </thead>
  <tr>
    <td>CPU</td>
    <td>1498</td>
    <td>1485</td>
    <td>101</td>
  </tr>
  <tr>
    <td>PG-Strom</td>
    <td>405</td>
    <td>422</td>
    <td>96</td>
  </tr>
  <tr>
    <td>PG-Stromによる速度向上率[%]</td>
    <td>370</td>
    <td>352</td>
    <td></td>
  </tr>
</table>

### JOIN句
<table>
  <thead>
    <tr>
      <td></td>
      <th>indexなし[ms]</th>
      <th>indexあり[ms]</th>
      <th>indexによる速度向上率[%]</th>
    </tr>
  </thead>
  <tr>
    <td>CPU</td>
    <td>15631</td>
    <td>15517</td>
    <td>101</td>
  </tr>
  <tr>
    <td>PG-Strom</td>
    <td>11826</td>
    <td>11697</td>
    <td>101</td>
  </tr>
  <tr>
    <td>PG-Stromによる速度向上率[%]</td>
    <td>132</td>
    <td>133</td>
    <td></td>
  </tr>
</table>

### 複合
<table>
  <thead>
    <tr>
      <td></td>
      <th>indexなし[ms]</th>
      <th>indexあり[ms]</th>
      <th>indexによる速度向上率[%]</th>
    </tr>
  </thead>
  <tr>
    <td>CPU</td>
    <td>6333</td>
    <td>6334</td>
    <td>100</td>
  </tr>
  <tr>
    <td>PG-Strom</td>
    <td>3290</td>
    <td>3187</td>
    <td>103</td>
  </tr>
  <tr>
    <td>PG-Stromによる速度向上率[%]</td>
    <td>192</td>
    <td>199</td>
    <td></td>
  </tr>
</table>

### おまけ(重複抽出)
<table>
  <thead>
    <tr>
      <td></td>
      <th>indexなし[ms]</th>
      <th>indexあり[ms]</th>
      <th>indexによる速度向上率[%]</th>
    </tr>
  </thead>
  <tr>
    <td>CPU</td>
    <td>10333</td>
    <td>10326</td>
    <td>100</td>
  </tr>
  <tr>
    <td>PG-Strom</td>
    <td>10558</td>
    <td>10533</td>
    <td>100</td>
  </tr>
  <tr>
    <td>PG-Stromによる速度向上率[%]</td>
    <td>98</td>
    <td>98</td>
    <td></td>
  </tr>
</table>

## 感想のような何か
index貼る方が労力も時間も節約になるな。。。
デカいデータベースの時はハードで殴るよりもindexやパーティションなどでチューニングするのが良さげ。
PG-StomはTBオーダーのデータベースになったら真価を発揮しそうな予感。あと、平均だとか計算するクエリ。