※このブログは2023年10月12日に公開された英語ブログ「Announcing TiDB 7.4: The Best Database Alternative for MySQL 8.0」の拙訳です。
過去10年間にわたり、MySQL 5.7は多くの企業や開発者にとって頼りになるオープンソースデータベースでした。しかし、オラクルが今月MySQL 5.7 のサポートを終了することで、多くのユーザはMySQL 8.0へのアップグレードか、必要なサポートとアップデートを受けられないか、という重大な決断を迫られています。
MySQL 8.0では、ウィンドウ関数、CTE (Common Table Expressions)、JSONサポートの強化など、多くのエキサイティングな機能が導入されただけでなく、洗練されたインデックス作成とクエリ実行の最適化により、優れたパフォーマンスが実現されています。
TiDBは、先進的なオープンソースの分散型SQLデータベースで、MySQLのエコシステムを設立当初から採用しています。TiDBはMySQLのプロトコルや構文コマンドと互換性があるため、MySQLクライアント、MySQLドライバ、MySQLユーティリティの一部をTiDB上で直接実行することができます。MySQL上で動作する大半のアプリケーションでは、コードの修正はほとんど必要ありません。
2023年10月12日にリリースされたTiDB 7.4は、MySQL 8.0の進化に合わせて、MySQL 5.7以降のMySQLとの互換性を正式に拡張し、MySQL 8.0の優れた機能の多くを採用しました。この強化された互換性により、MySQL 8.0アプリケーションの移行プロセスが大幅に効率化されます。
このブログでは、TiDB 7.4 Development Milestone Release (DMR)でサポートされるようになったMySQL 8.0の主な機能を紹介します:
- 共通テーブル式 (CTE)
- ウィンドウ関数
- リソース管理
- マルチバリューインデックス
- SET_VAR()ヒント
共通テーブル式
共通テーブル式 (CTE) は、1つのSQL文内で複数回再利用できる一時的な名前付き結果セットを定義するメカニズムを提供します。CTEを使用することで、複雑なSQLクエリの可読性と保守性が向上し、パフォーマンスが向上する可能性があります。
TiDBはバージョンv5.0からCTEをサポートしており、ANSI SQL 99標準とその再帰構文に合わせています。TiDB 7.4では、この互換性はTiDBのカラム型ストレージエンジンであるTiFlashにも拡張されています。
次の例では、authors (著者に関する情報を含む) とbook_authors (著者IDと書籍IDの関係を記録する) の2つのテーブルを使用しています。
SQL
mysql> desc authors;
+------------+--------------+------+------+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------+--------------+------+------+---------+-------+
| id | bigint(20) | NO | PRI | NULL | |
| name | varchar(100) | NO | | NULL | |
| gender | tinyint(1) | YES | | NULL | |
| birth_year | smallint(6) | YES | | NULL | |
| death_year | smallint(6) | YES | | NULL | |
+------------+--------------+------+------+---------+-------+
mysql> desc book_authors;
+-----------+------------+------+------+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------+------------+------+------+---------+-------+
| book_id | bigint(20) | NO | PRI | NULL | |
| author_id | bigint(20) | NO | PRI | NULL | |
+-----------+------------+------+------+---------+-------+
SQLでCTEを使用する利点を説明するために、最も年長の50人の著者がそれぞれ書いた本の数を検索するクエリを作成してみましょう:
SQL
mysql> WITH top_50_eldest_authors_cte AS (
-> SELECT a.id, a.name, (IFNULL(a.death_year, YEAR(NOW())) - a.birth_year) AS age
-> FROM authors a
-> ORDER BY age DESC
-> LIMIT 50
-> )
-> SELECT
-> ANY_VALUE(ta.id) AS author_id,
-> ANY_VALUE(ta.age) AS author_age,
-> ANY_VALUE(ta.name) AS author_name,
-> COUNT(*) AS books
-> FROM top_50_eldest_authors_cte ta
-> LEFT JOIN book_authors ba ON ta.id = ba.author_id
-> GROUP BY ta.id;
+-----------+------------+----------------------+-------+
| author_id | author_age | author_name | books |
+-----------+------------+----------------------+-------+
| 524470241 | 80 | Alexie Kirlin | 7 |
| 67511645 | 80 | Bridgette Tromp | 9 |
...
| 48355494 | 80 | Audrey Mayert | 7 |
+-----------+------------+----------------------+-------+
50 rows in set (0.23 sec)
このクエリは、著者ID、年齢、名前、そして最も年長の50人の著者がそれぞれ書いた本の総数を示す集計結果を提供します。この結果は0.23秒で効率的に得ることができました。
このクエリは、構造化された読みやすいSQL文を維持しながら、複雑なデータセットを管理・処理するCTEのパワーと有用性を例証しています。
ウィンドウ関数
ウィンドウ関数はしばしば分析関数と呼ばれ、データ分析、集計、ソート処理において極めて重要な役割を果たします。データのグループ化、並べ替え、傾向の特定などのタスクでは、ウィンドウ関数の使用が必要になることがよくあります。これらの関数は、面倒な自己結合やサブクエリに頼ることなく、複雑なデータ処理の課題に対処するSQLユーザーを手助けします。
TiDB 7.4はMySQL 8.0のウィンドウ関数をフルサポートしています。これらの関数のほとんどはTiFlashにプッシュダウンすることができます。リアルタイム分析用に調整されたTiFlashのアーキテクチャにより、TiDB 7.4でウィンドウ関数を使用することは、SQLの表現力と実行効率の強力な組み合わせをユーザに提供します。
リソース管理
効果的なリソース管理は、大規模データベースの最適なパフォーマンスと安定性を確保する上で極めて重要です。v7.1でのリソース管理の導入により、TiDBはクラスタリソースの割り当てと利用の改善において大きな進歩を遂げました。その利点は以下の通りです:
- 他のアプリケーションからのアプリケーション負荷の変化の影響を効果的に最小化
- バッチジョブやバックグラウンドタスクがコアビジネスに与える影響への対応
- クラスタ全体の速度を低下させる予期せぬSQLパフォーマンスの問題を軽減
TiDBとMySQLでは実装メカニズムが異なる場合がありますが、TiDBはリソースグループと関連ヒントを定義するMySQLの構文との互換性を確保しています。つまり、MySQLに慣れ親しんだユーザは、急な学習曲線や追加の移行コストなしに、シームレスにTiDBに移行することができます。
さらに、TiDBのリソース分離のアプローチは、重要なI/Oリソースを制御するための堅牢なメカニズムを提供します。この機能によってしばしばパフォーマンスが向上し、時にはMySQLで達成可能なパフォーマンスを上回ることさえあります。
次の例では、ユーザーusr1が1秒間に500RUを超えないように、リソース制御を行う方法を示します。
- クラスタの能力を見積もる。
mysql> CALIBRATE RESOURCE
- 500リクエスト/秒のリソースクォータを持つapp1リソースグループを作成します。
mysql> CREATE RESOURCE GROUP IF NOT EXISTS app1 RU_PER_SEC = 500;
- ユーザーusr1とリソースグループapp1を関連付け、このユーザーにリソース制限をかけます。
mysql> ALTER USER usr1 RESOURCE GROUP app1;
セッションのリソースグループを変更することもできます:
mysql> SET RESOURCE GROUP `app1`;
または、RESOURCE_GROUP()ヒントを使用して、文のリソース・グループを指定することもできます:
mysql> SELECT /*+ RESOURCE_GROUP(rg1) */ * FROM t limit 10;
強化されたutf8mb4文字セット
MySQL 8.0の注目すべき変更点の1つは、デフォルトの文字セットが包括的な utf8mb4に移行したことです。さらに、デフォルトの照合順序はutf8mb4_0900_ai_ciに変更されています。TiDB 7.4では、システムの移行を容易にするため、照合順序にutf8mb4_0900_ai_ciが追加されました。
MySQL互換の変数default_collation_for_utf8mb4をサポートしていることからも、TiDB の互換性へのこだわりがわかります。この機能は、utf8mb4文字セットのデフォルトのソート方法を調整する柔軟性を提供し、異なるMySQLバージョン間のシームレスな移行を実現します。その結果、TiDBユーザーは、特定のアプリケーション要件に合わせてデータベース設定を簡単にカスタマイズすることができます。
TiDBに移行する場合、照合順序の設定は元のMySQLのバージョンに大きく依存します:
- MySQL 8.0から移行する場合は、utf8mb4のデフォルトの照合順序をutf8mb4_0900_ai_ciに設定してください:
set global default_collation_for_utf8mb4='utf8mb4_0900_ai_ci';
- MySQL 5.7から移行する場合は、utf8mb4 のデフォルトの照合順序を utf8mb4_general_ciに設定してください:
set global default_collation_for_utf8mb4='utf8mb4_general_ci';
マルチバリューインデックス
MySQL 8.0のマルチバリューインデックスは、JSON配列のインデックスとアクセス方法を再定義する強力な機能です。マルチバリューインデックスは、従来のインデックス構造を進化させたものです。特に目を引くのは、JSON型の配列にインデックスを付けることができる点です。このユニークな機能により、JSONデータの迅速な検索が可能になり、クエリのパフォーマンスと効率が向上します。
TiDB 7.4では、MySQLの実装と同じマルチバリューインデックスをフルサポートしています。MEMBER OF()、JSON_CONTAINS()、JSON_OVERLAPS()などの主要な関数は、マルチバリューインデックスとシームレスに統合され、クエリプロセスを大幅に簡素化します。
TiDBへの移行を検討しているチームにとって、このサポートは手間のかからない移行を保証します。データモデリングを再構成したり、アプリケーションを調整したりする必要はありません。ユーザーは既存のプラクティスを維持し、慣れ親しんだ方法でJSONデータを操作し続けることができます。
例えば、JSON型のカラムにすべての詳細をカプセル化した顧客情報テーブルのシナリオを考えてみましょう。このカラムは、顧客が居住する可能性のあるさまざまな都市をキャプチャするために配列構造を採用しています。
マルチバリューインデックスを使用しない場合、北京にいる顧客を検索するには、このクエリはテーブルをフルスキャンする必要があります:
SELECT name FROM customer
WHERE 'beijing' MEMBER OF $.city;
city配列に複数値のインデックスを作成した後、上記のクエリはインデックスを使用して、一致するすべてのレコードを素早く特定することができます:
ALTER TABLE customers add index idx_city (name, (CAST(custinfo->'$.city' AS char(20) ARRAY)))
注意: さまざまな理由により、データベースのクエリオプティマイザが自動的にマルチバリューインデックスを利用しない場合があります。このような場合、オプティマイザ・ヒント USE_INDEX() または USE_INDEX_MERGE() を使用して、指定したインデックスを利用するようにオプティマイザを “誘導 “することができます。
SET_VAR()ヒント
SET_VAR ()
は、グローバル変数やセッション変数に影響を与えることなく、特定のSQL文の実行を微調整するための多用途なヒントです。TiDB 7.4はこのヒントをサポートしており、特定のSQL文のシステム変数を簡単にカスタマイズすることができます。これにより、きめ細かな制御が可能になり、変更が不用意に他の操作に影響を与えないようにすることができます。
例えば、大きなテーブルを分析・処理する場合、/*+ set_var(tidb_executor_concurrency=20 */
というヒントでSQL実行の同時実行性を高めることができます:
SELECT /*+ set_var(tidb_executor_concurrency=20) */
l_orderkey,
SUM(
l_extendedprice * (1 - l_discount)
) AS revenue,
o_orderdate,
o_shippriority
FROM
customer,
orders,
lineitem
WHERE
c_mktsegment = 'BUILDING'
AND c_custkey = o_custkey
AND l_orderkey = o_orderkey
AND o_orderdate < DATE '1996-01-01'
AND l_shipdate > DATE '1996-02-01'
GROUP BY
l_orderkey,
o_orderdate,
o_shippriority
ORDER BY
revenue DESC,
o_orderdate
limit 10;
/*+ set_var(tidb_isolation_read_engines='tidb,tiflash') */
ヒントを使用すると、今作成したクエリを強制的にTiFlashを選択し、他のクエリは変更しないようにすることができます:
SELECT /*+ set_var(tidb_isolation_read_engines='tidb,tiflash') */
l_orderkey,
SUM(
l_extendedprice * (1 - l_discount)
) AS revenue,
o_orderdate,
o_shippriority
FROM
customer,
orders,
lineitem
WHERE
c_mktsegment = 'BUILDING'
AND c_custkey = o_custkey
AND l_orderkey = o_orderkey
AND o_orderdate < DATE '1996-01-01'
AND l_shipdate > DATE '1996-02-01'
GROUP BY
l_orderkey,
o_orderdate,
o_shippriority
ORDER BY
revenue DESC,
o_orderdate
limit 10;
詳細はTiDBのドキュメントをご参照ください。
スケーラブルでクラウドネイティブなMySQLの代替となるTiDBへの移行
最後に、TiDB 7.4は、MySQL 5.7およびMySQL 8.0の両方と高い互換性を維持する強力なデータベースソリューションとしての地位をさらに強化しています。MySQL 8.0の最新機能をサポートすることで、TiDBは先進的な機能と使い慣れた機能を組み合わせた包括的なプラットフォームをユーザーに提供します。このような互換性と革新性への一貫した取り組みにより、TiDBは両方のデータベースの長所を活用したい企業にとって魅力的な選択肢となっています。
MySQL 8.0のワークロードをTiDBでテストし、互換性の問題があればお知らせください。私たちのチームは、新しいリリースのたびにTiDBのMySQL互換性とパフォーマンスを継続的に改善しています。移行方法については、MySQLからTiDBへの移行ガイドをご覧ください。
TiDB Cloud Dedicated
TiDB Cloudのエンタープライズ版。
専用VPC上に構築された専有DBaaSでAWSとGoogle Cloudで利用可能。
TiDB Cloud Serverless
TiDB Cloudのライト版。
TiDBの機能をフルマネージド環境で使用でき無料かつお客様の裁量で利用開始。