説明
V4.2.x系では、この変数はV4.2.5およびV4.2.1 BP9バージョンから導入されました。
機能の概要
range_index_dive_limitは、オプティマイザーがストレージ層で行を推定する際の範囲数の制限を示します。
権限要件
クエリ変数
グローバルレベル
sysテナントとすべてのユーザーテナントは
SHOW VARIABLESステートメント、またはSYS.TENANT_VIRTUAL_GLOBAL_VARIABLEビュー(Oracleモード)およびinformation_schema.GLOBAL_VARIABLESビュー(MySQLモード)を使用してグローバルシステム変数の値を確認できます。セッションレベル
sysテナントとすべてのユーザーテナントは
SHOW VARIABLESステートメント、またはSYS.TENANT_VIRTUAL_SESSION_VARIABLEビュー(Oracleモード)およびinformation_schema.SESSION_VARIABLESビュー(MySQLモード)を使用してセッションシステム変数の値を確認できます。
変数の変更
グローバル有効
- sysテナントはグローバルシステム変数の値を直接変更できます。
- MySQLユーザーテナントは
SUPERまたはALTER SYSTEM権限を持っている必要があります。 - Oracleユーザーテナントは
ALTER SYSTEM権限を持っている必要があります。
セッション有効
sysテナントとすべてのユーザーテナントは、自身のテナントに属するセッションシステム変数の値を直接変更できます。
プロパティの説明
プロパティ |
説明 |
|---|---|
| パラメータタイプ | Int |
| デフォルト値 | 10 |
| 値の範囲 | [0, INT64_MAX]
説明ここで:
|
| 適用範囲 |
|
| 変更は可能か | はい。SET ステートメントを使用して変更できます。 |
使用方法
この変数を変更することで、オプティマイザーがストレージ層で行推定を行う際の範囲数の制限を制御します:
- 範囲数がこの変数より少ない場合、常にすべての範囲を選択してストレージ層で行推定を行います。
- 範囲数がこの変数以上の場合、ランダムに
range_index_dive_limit個の範囲を選択してストレージ層で行推定を行い、推定結果を比例して拡大します。 - この変数が0の場合、常にすべての範囲を選択してストレージ層で行推定を行います。
range_index_dive_limitとpartition_index_dive_limitがどちらも負の数値の場合、ストレージ層での行推定戦略は旧バージョンにロールバックし、単一パーティションの10個の範囲以内でのみストレージ層で行推定を行います。
設定例
テーブルを作成し、データを挿入します。
obclient> CREATE TABLE t1(c1 int, c2 int, index i1(c1)); Query OK, 0 rows affected (0.173 sec) obclient> INSERT INTO t1 SELECT 1,1 FROM table(generator(10)); Query OK, 10 rows affected (0.003 sec) Records: 10 Duplicates: 0 Warnings: 0 obclient> INSERT INTO t1 SELECT 2,2 FROM table(generator(20)); Query OK, 20 rows affected (0.001 sec) Records: 20 Duplicates: 0 Warnings: 0 obclient> INSERT INTO t1 SELECT 3,3 FROM table(generator(30)); Query OK, 30 rows affected (0.001 sec) Records: 30 Duplicates: 0 Warnings: 0実行計画を確認します。デフォルトのシナリオでは、10個の範囲を超えない場合はすべてストレージ層で行推定が行われます。
obclient> EXPLAIN SELECT c1 FROM t1 WHERE c1 in (1,2,3); +---------------------------------------------------------------------------------------------------------+ | Query Plan | +---------------------------------------------------------------------------------------------------------+ | ================================================== | | |ID|OPERATOR |NAME |EST.ROWS|EST.TIME(us)| | | -------------------------------------------------- | | |0 |TABLE RANGE SCAN|t1(i1)|60 |11 | | | ================================================== | | Outputs & filters: | | ------------------------------------- | | 0 - output([t1.c1]), filter(nil), rowset=256 | | access([t1.c1]), partitions(p0) | | is_index_back=false, is_global_index=false, | | range_key([t1.c1], [t1.__pk_increment]), range(1,MIN ; 1,MAX), (2,MIN ; 2,MAX), (3,MIN ; 3,MAX), | | range_cond([t1.c1 IN (1, 2, 3)]) | +---------------------------------------------------------------------------------------------------------+ 12 rows in set (0.008 sec)変数を変更し、1つの範囲のみを選択してストレージ層で行推定を行います。
obclient> SET range_index_dive_limit = 1; Query OK, 0 rows affected (0.001 sec)実行計画を確認すると、ストレージ層で行推定を行ったのは3番目の範囲(3, MIN; 3, MAX)のみであり、推定結果は
30 * 3 = 90であることがわかります。obclient> EXPLAIN SELECT c1 FROM t1 WHERE c1 in (1,2,3); +---------------------------------------------------------------------------------------------------------+ | Query Plan | +---------------------------------------------------------------------------------------------------------+ | ================================================== | | |ID|OPERATOR |NAME |EST.ROWS|EST.TIME(us)| | | -------------------------------------------------- | | |0 |TABLE RANGE SCAN|t1(i1)|90 |12 | | | ================================================== | | Outputs & filters: | | ------------------------------------- | | 0 - output([t1.c1]), filter(nil), rowset=256 | | access([t1.c1]), partitions(p0) | | is_index_back=false, is_global_index=false, | | range_key([t1.c1], [t1.__pk_increment]), range(1,MIN ; 1,MAX), (2,MIN ; 2,MAX), (3,MIN ; 3,MAX), | | range_cond([t1.c1 IN (1, 2, 3)]) | +---------------------------------------------------------------------------------------------------------+ 12 rows in set (0.003 sec)