JoinHint が有効にならないのはなぜですか?

この記事は Huawei Cloud Community から共有されたものです。「 JoinHint が有効にならないのはなぜですか [Bloom! GaussDB (DWS) Cloud Native Data Warehouse】》、作者: 猿に誘われた援軍ですか?

導入

データベース ヒントに関しては、ほぼすべての DBA がこの強力な機能を知っています。 GaussDB (DWS) では、Hint を使用して SQL の実行計画に介入できますが、日常業務では多くの開発者が Hint を深く理解しておらず、Hint の失敗に遭遇しても無力であることがよくあります。
今回は、JoinHint が機能しない原因を事例から掘り下げて分析し、読者の皆様にも「なぜ分かる」ようにしていきます。 (この記事では、ヒントの基本的な構文については説明しません)。

問題事例

カーネル バージョン GaussDB 8.1.3

問題の説明 2 つのテーブルが相互に関連しており、結合メソッドに介入するためにハッシュ結合ヒントが使用されていますが、ヒントが有効になりません

問題のあるユースケース

CREATE TABLE 作業項目 (
    言語文字の変化(10)、
    ユーザー ID 文字が変化する (240)、
    Opiontype 文字可変 (240)、
    stid 文字の可変処理 (240)、
    workitemid 文字可変(240)、
    type_name 文字可変 (240)、
    type_code 文字可変 (240)、
    createtime タイムゾーンなしのタイムスタンプ、
    タイムゾーンなしの終了時刻タイムスタンプ、
    拒否しない合計数値、
    dws_created_time タイムゾーンなしのタイムスタンプ
)
WITH (方向=列、圧縮=低、colversion=2.0、enable_delta=false)
DISTRIBUTE BY HASH(workitemid);

CREATE TABLE 平日 (
    mm タイムゾーン付きのタイムスタンプ、
    rn 数値
)
WITH (方向=列、圧縮=低、colversion=2.0、enable_delta=false)
ハッシュで分散(mm);

説明する
SELECT /*+ ハッシュジョイン(c d) */
    c.userid,c.type_name,c.type_code,count(1) num
FROM workitem c INNER JOIN workday d ON c.createtime = d.mm
    WHERE c.createtime >= '2023-09-01'かつ c.endtime < '2023-10-01'
    GROUP BY c.userid、c.type_name、c.type_code;

警告: 未使用のヒント: HashJoin(c d)
                                                                                 クエリプラン
-------------------------------------------------- -------------------------------------------------- -------------------------------------------------- ------------------------
  ID |操作 | E行 | Eメモリー | E幅 |電子コスト
 ----+------------------------------------------ --------+--------+----------+-----------+---------
   1 | ->行アダプター | 2 | | 1502 | 33.12
   2 | ->ベクトルソニックハッシュ集合体 | 2 | | 1502 | 33.12
   3 | ->ベクターストリーミング(種類:GATHER) | 4 | | 1502 | 33.12
   4 | ->ベクトルソニックハッシュ集合体 | 4 | 16MB | 1502 | 12月27日
   5 | ->ベクトル ネスト ループ (6,8) | 5 | 1MB | 1494 | 8月27日
   6 | ->ベクターストリーミング(種類:ブロードキャスト) | 14 | 2MB | 8 | 13.68
   7 | -> C 平日にスキャンを保存する | 7 | 1MB | 8 | 13.05
   8 | ->ベクトルマテリアライズ | 5 | 16MB | 1502 | 9月13日
   9 | -> C 作業項目 c にスキャンを保存する | 5 | 1MB | 1502 | 13.08

         ランタイム分析情報
 -------------------------------------------
         「public.workitem」実行時間: 25.794ms
         「パブリック.ワークデイ」実行時間: 18.098ms

                                                               述語情報 (プラン ID によって識別される)
 -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- --------------------
   5 -- ベクターネストループ (6,8)
         結合フィルター: (c.createtime = d.mm)
   7 --C 平日にスキャンを保存する
         フィルター: (mm >= '2023-09-01 00:00:00'::タイムゾーンなしのタイムスタンプ)
         プッシュダウン述語フィルター: (mm >= '2023-09-01 00:00:00'::タイムゾーンなしのタイムスタンプ)
   9 --CStore ワークアイテム c のスキャン
         フィルター: ((createtime >= '2023-09-01 00:00:00'::タイムゾーンなしのタイムスタンプ) AND (endtime < '2023-10-01 00:00: 00'::タイムゾーンなしのタイムスタンプ))
         プッシュダウン述語フィルター: ((createtime >= '2023-09-01 00:00:00'::timestamp without timezone) AND (endtime < '2023-10-01 00: 00:00'::タイムゾーンなしのタイムスタンプ))

   ====== クエリの概要 =====
 -----------------------------
 システム利用可能メモリ: 4710400KB
 クエリ最大メモリ: 4710400KB
 クエリの推定メモリ: 5271KB
(33行)

問題を特定する

ネストループ パスを閉じて、ハッシュ プランが生成できるかどうかを確認してみます。

Enable_nestloop = オフに設定します。

Enable_mergejoin = オフに設定します。

Enable_hashjoin = オンに設定します。

警告: 未使用のヒント: HashJoin(c d)
                                                                                 クエリプラン
-------------------------------------------------- -------------------------------------------------- -------------------------------------------------- ------------------------
  ID |操作 | E行 | Eメモリー | E幅 |電子コスト
 ----+------------------------------------------ --------+--------+----------+-----------+---------
   1 | ->行アダプター | 2 | | 1502 | 33.12
   2 | ->ベクトルソニックハッシュ集合体 | 2 | | 1502 | 33.12
   3 | ->ベクターストリーミング(種類:GATHER) | 4 | | 1502 | 33.12
   4 | ->ベクトルソニックハッシュ集合体 | 4 | 16MB | 1502 | 12月27日
   5 | ->ベクトル ネスト ループ (6,8) | 5 | 1MB | 1494 | 8月27日
   6 | ->ベクターストリーミング(種類:ブロードキャスト) | 14 | 2MB | 8 | 13.68
   7 | -> C 平日にスキャンを保存する | 7 | 1MB | 8 | 13.05
   8 | ->ベクトルマテリアライズ | 5 | 16MB | 1502 | 9月13日
   9 | -> C 作業項目 c にスキャンを保存する | 5 | 1MB | 1502 | 13.08

                                                               述語情報 (プラン ID によって識別される)
 -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- --------------------
   5 -- ベクターネストループ (6,8)
         結合フィルター: (c.createtime = d.mm)
   7 --C 平日にスキャンを保存する
         フィルター: (mm >= '2023-09-01 00:00:00'::タイムゾーンなしのタイムスタンプ)
         プッシュダウン述語フィルター: (mm >= '2023-09-01 00:00:00'::タイムゾーンなしのタイムスタンプ)
   9 --CStore ワークアイテム c のスキャン
         フィルター: ((createtime >= '2023-09-01 00:00:00'::タイムゾーンなしのタイムスタンプ) AND (endtime < '2023-10-01 00:00: 00'::タイムゾーンなしのタイムスタンプ))
         プッシュダウン述語フィルター: ((createtime >= '2023-09-01 00:00:00'::timestamp without timezone) AND (endtime < '2023-10-01 00: 00:00'::タイムゾーンなしのタイムスタンプ))

   ====== クエリの概要 =====
 -----------------------------
 システム利用可能メモリ: 4710400KB
 クエリ最大メモリ: 4710400KB
 クエリの推定メモリ: 5271KB
(28行)

ネストループ パスを閉じた後もネストループ プランは生成され、ペナルティ コストは E コスト価格に追加されません。これは、シナリオ ステートメント自体がハッシュ結合をサポートしていないことを示します。

関連する式 (c.createtime = d.mm) を確認します

、ハッシュジョインがサポートされているかどうかを確認します。

  • 関連付け式はフィールド関連付けであり、関数のネストはありません。
  • アソシエーション式の両側のデータ型はタイムゾーンなしのタイムスタンプとタイムゾーンありのタイムスタンプです。システム テーブル pg_operator を通じてハッシュジョインがサポートされているかどうかを確認してください。
postgres=# select * from pg_operator where oprname = '=' oprleft = 'timestamp'::regtype および oprright = 'timestamptz'::regtype;
-[ レコード 1 ]+--------------------------
オプション名 | =
opr 名前空間 | 11
オーナー | 10
いいえ | b
oprcanmerge | t
オプカンハッシュ | f
オプレフト | 1114
わかりました | 1184
結果 | 16
オペコム | 2542
着る | 2539
オペコード | timestamp_eq_timestamptz
オプレスト |エクセル
参加する |エクジョインセル
  • 結果は、oprcanhash が false であることを確認します。これは、オペレーターがハッシュ接続をサポートしていないことを意味します。その理由は、左側のデータにはタイム ゾーンがなく、右側のデータにはタイム ゾーンがあるためです。比較する場合、タイム ゾーンの問題が発生します。を最初に処理する必要があり、保存された値を直接判断に使用することはできません。

改善方法

タイムスタンプ型の同値対応付けとタイムスタンプの同値対応付けがハッシュ接続をサポートしていることをシステムテーブルで確認します。

postgres=# select * from pg_operator where oprname = '=' and oprleft = oprright および oprleft in('timestamp'::regtype,'timestamptz'::regtype);
-[ レコード 1 ]+---------------
オプション名 | =
opr 名前空間 | 11
オーナー | 10
いいえ | b
oprcanmerge | t
オプカンハッシュ | t
オプレフト | 1184
わかりました | 1184
結果 | 16
オペコム | 1320
着る | 1321
オペコード |タイムスタンプ_eq
オプレスト |エクセル
参加する |エクジョインセル
-[ レコード 2 ]+---------------
オプション名 | =
opr 名前空間 | 11
オーナー | 10
いいえ | b
oprcanmerge | t
オプカンハッシュ | t
オプレフト | 1114
わかりました | 1114
結果 | 16
オペコム | 2060年
着る | 2061年
オペコード |タイムスタンプ_eq
オプレスト |エクセル
参加する |エクジョインセル

関連付けられた条件に型変換を追加して、両側の型が一貫していることを確認します。つまり、(c.createtime::timestamptz = d.mm) または (c. createtime =  d.mm::timestamp)。

postgres=#説明します
postgres-# SELECT /*+ hashjoin(c d) */
postgres-# c.userid,c.type_name,c.type_code,count(1) num
postgres-# FROM workitem c INNER JOIN workday d ON c.createtime::timestamptz = d.mm
postgres-# WHERE c.createtime >= '2023-09-01'かつ c.endtime < '2023-10-01'
postgres-# GROUP BY c.userid,c.type_name,c.type_code;
                                                                                 クエリプラン
-------------------------------------------------- -------------------------------------------------- -------------------------------------------------- ------------------------
  ID |操作 | E行 | Eメモリー | E幅 |電子コスト
 ----+------------------------------------------ --------+--------+----------+-----------+---------
   1 | ->行アダプター | 2 | | 1502 | 34.29
   2 | ->ベクトルソニックハッシュ集合体 | 2 | | 1502 | 34.29
   3 | ->ベクターストリーミング(種類:GATHER) | 4 | | 1502 | 34.29
   4 | ->ベクトルソニックハッシュ集合体 | 4 | 16MB | 1502 | 28.29
   5 | ->ベクトル ソニック ハッシュ結合 (6,8) | 5 | 16MB | 1494 | 28.25
   6 | ->ベクターストリーミング(種類:ブロードキャスト) | 40 | 2MB | 8 | 6月15日
   7 | -> C 平日にスキャンを保存する | 20 | 1MB | 8 | 13.01
   8 | -> C 作業項目 c にスキャンを保存する | 5 | 1MB | 1502 | 13.08

                                                               述語情報 (プラン ID によって識別される)
 -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- --------------------
   5 -- ベクトル ソニック ハッシュ結合 (6,8)
         ハッシュ条件: (d.mm = (c.createtime)::タイムゾーン付きのタイムスタンプ)
   8 --CStore 作業項目 c のスキャン
         フィルター: ((createtime >= '2023-09-01 00:00:00'::タイムゾーンなしのタイムスタンプ) AND (endtime < '2023-10-01 00:00: 00'::タイムゾーンなしのタイムスタンプ))
         プッシュダウン述語フィルター: ((createtime >= '2023-09-01 00:00:00'::timestamp without timezone) AND (endtime < '2023-10-01 00: 00:00'::タイムゾーンなしのタイムスタンプ))

   ====== クエリの概要 =====
 -----------------------------
 システム利用可能メモリ: 4710400KB
 クエリ最大メモリ: 4710400KB
 クエリの推定メモリ: 5530KB
(24行)

postgres=#説明します
SELECT /*+ ハッシュジョイン(c d) */
    c.userid,c.type_name,c.type_code,count(1) num
FROM workitem c INNER JOIN workday d ON c.createtime = d.mm::timestamp
    WHERE c.createtime >= '2023-09-01'かつ c.endtime < '2023-10-01'
    GROUP BY c.userid、c.type_name、c.type_code;
                                                                                 クエリプラン
-------------------------------------------------- -------------------------------------------------- -------------------------------------------------- ------------------------
  ID |操作 | E行 | Eメモリー | E幅 |電子コスト
 ----+------------------------------------------ --------+--------+----------+-----------+---------
   1 | ->行アダプター | 2 | | 1502 | 32.91
   2 | ->ベクトルソニックハッシュ集合体 | 2 | | 1502 | 32.91
   3 | ->ベクターストリーミング(種類:GATHER) | 4 | | 1502 | 32.91
   4 | ->ベクトルソニックハッシュ集合体 | 4 | 16MB | 1502 | 26.91
   5 | ->ベクトル ソニック ハッシュ結合 (6,8) | 5 | 16MB | 1494 | 26.87
   6 | ->ベクターストリーミング(種類:ブロードキャスト) | 14 | 2MB | 8 | 13.71
   7 | -> C 平日にスキャンを保存する | 7 | 1MB | 8 | 13.08
   8 | -> C 作業項目 c にスキャンを保存する | 5 | 1MB | 1502 | 13.08

                                                               述語情報 (プラン ID によって識別される)
 -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- --------------------
   5 -- ベクトル ソニック ハッシュ結合 (6,8)
         ハッシュ条件: ((d.​​mm)::タイムゾーンなしのタイムスタンプ = c.createtime)
   7 --C 平日にスキャンを保存する
         フィルタ: ((mm)::タイムゾーンなしのタイムスタンプ >= '2023-09-01 00:00:00'::タイムゾーンなしのタイムスタンプ)
   8 --CStore 作業項目 c のスキャン
         フィルター: ((createtime >= '2023-09-01 00:00:00'::タイムゾーンなしのタイムスタンプ) AND (endtime < '2023-10-01 00:00: 00'::タイムゾーンなしのタイムスタンプ))
         プッシュダウン述語フィルター: ((createtime >= '2023-09-01 00:00:00'::timestamp without timezone) AND (endtime < '2023-10-01 00: 00:00'::タイムゾーンなしのタイムスタンプ))

   ====== クエリの概要 =====
 -----------------------------
 システム利用可能メモリ: 4710400KB
 クエリ最大メモリ: 4710400KB
 クエリの推定メモリ: 5530KB
(26行)

知識のまとめ

実際の使用中にヒントが有効になる理由は数多くあります。ハッシュジョイン ヒントトラブルシューティングの概要を次に示します。手順は参考用です。

  • ヒント内のテーブル名が正しいかどうか、重複した名前があるかどうか、現在のレイヤーに表示されているかどうかを確認します。このようなシナリオでは、通常、説明にプロンプ​​トが表示されるため、自分で確認できます。
  • 関連するヒント内のテーブル名がプロモートされ、その結果テーブル名が存在しなくなるかどうかを確認します。このようなシナリオは、通常、Explain で要求されます。
postgres=#説明します
SELECT /*+ ハッシュジョイン(c d) */
    c.userid,c.type_name,c.type_code,count(1) num
FROM workitem c INNER JOIN (select * from workday where mm >= '2023-09-01') d ON c.createtime = d.mm::timestamp
    WHERE c.createtime >= '2023-09-01'かつ c.endtime < '2023-10-01'
    GROUP BY c.userid、c.type_name、c.type_code;
警告: エラーのヒント: HashJoin(c d)、関係名 "d"見つかりません。
                                                                                 クエリプラン
-------------------------------------------------- -------------------------------------------------- -------------------------------------------------- ------------------------
  ID |操作 | E行 | Eメモリー | E幅 |電子コスト
 ----+------------------------------------------ --------+--------+----------+-----------+---------
   1 | ->行アダプター | 2 | | 1502 | 32.78
   2 | ->ベクトルソニックハッシュ集合体 | 2 | | 1502 | 32.78
   3 | ->ベクターストリーミング(種類:GATHER) | 4 | | 1502 | 32.78
   4 | ->ベクトルソニックハッシュ集合体 | 4 | 16MB | 1502 | 26.78
   5 | ->ベクトル ソニック ハッシュ結合 (6,8) | 5 | 16MB | 1494 | 26.74
   6 | ->ベクターストリーミング(種類:ブロードキャスト) | 10 | 2MB | 8 | 13.58
   7 | -> Cストア 平日にスキャン | 5 | 1MB | 8 | 13.11
   8 | -> C 作業項目 c にスキャンを保存する | 5 | 1MB | 1502 | 13.08

                                                               述語情報 (プラン ID によって識別される)
 -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- --------------------
   5 -- ベクトル ソニック ハッシュ結合 (6,8)
         ハッシュ条件: ((workday.mm)::タイムゾーンなしのタイムスタンプ = c.createtime)
   7 --CStore 平日のスキャン
         フィルター: ((mm >= '2023-09-01 00:00:00+08'::タイムゾーン付きのタイムスタンプ) AND ((mm)::タイムゾーンなしのタイムスタンプ >=  39;2023-09-01 00:00:00'::タイムゾーンなしのタイムスタンプ))
         プッシュダウン述語フィルター: (mm >= '2023-09-01 00:00:00+08'::タイムゾーン付きタイムスタンプ)
   8 --CStore 作業項目 c のスキャン
         フィルター: ((createtime >= '2023-09-01 00:00:00'::タイムゾーンなしのタイムスタンプ) AND (endtime < '2023-10-01 00:00: 00'::タイムゾーンなしのタイムスタンプ))
         プッシュダウン述語フィルター: ((createtime >= '2023-09-01 00:00:00'::timestamp without timezone) AND (endtime < '2023-10-01 00: 00:00'::タイムゾーンなしのタイムスタンプ))

   ====== クエリの概要 =====
 -----------------------------
 システム利用可能メモリ: 4710400KB
 クエリ最大メモリ: 4710400KB
 クエリの推定メモリ: 5530KB
(27行)

この状況に対応して、バージョン 8.2.0 以降では、マージ ヒントを追加せずにサブクエリのプロモーションを無効にして、ヒントの失敗の問題を回避できます。

結合パス パラメーターを使用して、ターゲット パスが有効かどうかを確認します。

-- たとえば、他のパス パラメータをオフにして、特定のパスが到達可能かどうかを確認します。
Enable_nestloop = オフに設定します。
Enable_mergejoin = オフに設定します。
Enable_hashjoin = オンに設定します。

関連付けられた条件に揮発性関数が存在するかどうかを確認します。

postgres=# 関数 gettimediff(timestamp) を作成または置換すると、間隔言語 SQL が 'select $1-timeofday()::timestamp' として返されます。揮発性;
関数の作成
postgres=#説明します
SELECT /*+ ハッシュジョイン(c d) */
    c.userid,c.type_name,c.type_code,count(1) num
FROM workitem c INNER JOIN workday d ON gettimediff(c.createtime) = gettimediff(d.mm::timestamp)
    WHERE c.createtime >= '2023-09-01'かつ c.endtime < '2023-10-01'
    GROUP BY c.userid、c.type_name、c.type_code;
警告: 未使用のヒント: HashJoin(c d)
                                                                               クエリプラン
-------------------------------------------------- -------------------------------------------------- -------------------------------------------------- -------------------
  ID |操作 | E行 | E幅 |電子コスト
 ----+------------------------------------------ ----------+--------+--------+----------
   1 | ->ハッシュ集計 | 5 | 1502 | 3.10
   2 | ->入れ子になったループ (3,4) | 5 | 1494 | 3.00
   3 | ->作業項目「_REMOTE_TABLE_QUERY_」のデータ ノード スキャン| 5 | 1502 | 0.00
   4 | ->平日「_REMOTE_TABLE_QUERY_」のデータ ノード スキャン| 20 | 8 | 0.00

                                                              述語情報 (プラン ID によって識別される)
 -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- -----------------
   2 -- ネストされたループ (3,4)
         結合フィルター: ((c.createtime - (timeofday())::タイムゾーンなしのタイムスタンプ) = ((d.​​mm)::タイムゾーンなしのタイムスタンプ - (timeofday())::タイムゾーンなしのタイムスタンプ))
(11行)

関連条件の 2 つのテーブルのフィールドが等号の両側にあるかどうかを確認し、等号の両側にない場合は調整します。

postgres=#説明します
SELECT /*+ ハッシュジョイン(c d) */
    c.userid,c.type_name,c.type_code,count(1) num
FROM 作業項目 c INNER JOIN workday d ON ifnull(c.createtime,d.mm) = now()
    WHERE c.createtime >= '2023-09-01'かつ c.endtime < '2023-10-01'
    GROUP BY c.userid、c.type_name、c.type_code;
警告: 未使用のヒント: HashJoin(c d)
                                                                                 クエリプラン
-------------------------------------------------- -------------------------------------------------- -------------------------------------------------- ------------------------
  ID |操作 | E行 | Eメモリー | E幅 |電子コスト
 ----+------------------------------------------ --------+--------+----------+-----------+---------
   1 | ->行アダプター | 1 | | 1502 | 35.37
   2 | ->ベクトルソニックハッシュ集合体 | 1 | | 1502 | 35.37
   3 | ->ベクターストリーミング(種類:GATHER) | 2 | | 1502 | 35.37
   4 | ->ベクトルソニックハッシュ集合体 | 2 | 16MB | 1502 | 29.37
   5 | ->ベクトル ネスト ループ (6,8) | 2 | 1MB | 1494 | 29.35
   6 | ->ベクターストリーミング(種類:ブロードキャスト) | 40 | 2MB | 8 | 6月15日
   7 | -> C 平日にスキャンを保存する | 20 | 1MB | 8 | 13.01
   8 | ->ベクトルマテリアライズ | 5 | 16MB | 1502 | 9月13日
   9 | -> C 作業項目 c にスキャンを保存する | 5 | 1MB | 1502 | 13.08

                                                               述語情報 (プラン ID によって識別される)
 -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- --------------------
   5 -- ベクターネストループ (6,8)
         結合フィルター: (COALESCE((c.createtime)::タイムゾーン付きのタイムスタンプ、d.mm) = now())
   9 --CStore ワークアイテム c のスキャン
         フィルター: ((createtime >= '2023-09-01 00:00:00'::タイムゾーンなしのタイムスタンプ) AND (endtime < '2023-10-01 00:00: 00'::タイムゾーンなしのタイムスタンプ))
         プッシュダウン述語フィルター: ((createtime >= '2023-09-01 00:00:00'::timestamp without timezone) AND (endtime < '2023-10-01 00: 00:00'::タイムゾーンなしのタイムスタンプ))

   ====== クエリの概要 =====
 -----------------------------
 システム利用可能メモリ: 4710400KB
 クエリ最大メモリ: 4710400KB
 クエリの推定メモリ: 5275KB
(25行)

関連条件が等価関連かどうかを確認し、等価関連でない場合は調整します。

postgres=#説明します
SELECT /*+ ハッシュジョイン(c d) */
    c.userid,c.type_name,c.type_code,count(1) num
FROM workitem c INNER JOIN workday d ON c.createtime::timestamptz > d.mm
    WHERE c.createtime >= '2023-09-01'かつ c.endtime < '2023-10-01'
    GROUP BY c.userid、c.type_name、c.type_code;
警告: 未使用のヒント: HashJoin(c d)
                                                                                 クエリプラン
-------------------------------------------------- -------------------------------------------------- -------------------------------------------------- ------------------------
  ID |操作 | E行 | Eメモリー | E幅 |電子コスト
 ----+------------------------------------------ --------+--------+----------+-----------+---------
   1 | ->行アダプター | 5 | | 1502 | 35.41
   2 | ->ベクトルソニックハッシュ集合体 | 5 | | 1502 | 35.41
   3 | ->ベクターストリーミング(種類:GATHER) | 10 | | 1502 | 35.41
   4 | ->ベクトルソニックハッシュ集合体 | 10 | 16MB | 1502 | 29.41
   5 | ->ベクトル ネスト ループ (6,8) | 33 | 1MB | 1494 | 29.20
   6 | ->ベクターストリーミング(種類:ブロードキャスト) | 40 | 2MB | 8 | 6月15日
   7 | -> C 平日にスキャンを保存する | 20 | 1MB | 8 | 13.01
   8 | ->ベクトルマテリアライズ | 5 | 16MB | 1502 | 9月13日
   9 | -> C 作業項目 c にスキャンを保存する | 5 | 1MB | 1502 | 13.08

                                                               述語情報 (プラン ID によって識別される)
 -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- --------------------
   5 -- ベクターネストループ (6,8)
         結合フィルター: ((c.createtime)::タイムゾーンのタイムスタンプ > d.mm)
   9 --CStore ワークアイテム c のスキャン
         フィルター: ((createtime >= '2023-09-01 00:00:00'::タイムゾーンなしのタイムスタンプ) AND (endtime < '2023-10-01 00:00: 00'::タイムゾーンなしのタイムスタンプ))
         プッシュダウン述語フィルター: ((createtime >= '2023-09-01 00:00:00'::timestamp without timezone) AND (endtime < '2023-10-01 00: 00:00'::タイムゾーンなしのタイムスタンプ))

   ====== クエリの概要 =====
 -----------------------------
 システム利用可能メモリ: 4710400KB
 クエリ最大メモリ: 4710400KB
 クエリの推定メモリ: 5281KB
(25行)

リレーションシップの両側のデータ型を確認し、ハッシュ接続がサポートされているかどうかを pg_operator.oprcanhash で確認し、サポートされていない場合はサポートされている演算子に書き換える必要があります。

postgres=# select * from pg_operator where oprname = '=' oprleft = 'timestamp'::regtype および oprright = 'timestamptz'::regtype;
-[ レコード 1 ]+--------------------------
オプション名 | =
opr 名前空間 | 11
オーナー | 10
いいえ | b
oprcanmerge | t
オプカンハッシュ | f
オプレフト | 1114
わかりました | 1184
結果 | 16
オペコム | 2542
着る | 2539
オペコード | timestamp_eq_timestamptz
オプレスト |エクセル
参加する |エクジョインセル

Leading(c e) など、結合順序を指定するヒントの場合、ロジック自体に競合が発生してヒントが失敗する可能性があります。

postgres=# Explain SELECT /*+ leading(c e) */
    c.userid,c.type_name,c.type_code,count(1) num
FROM 作業項目 c LEFT JOIN workday d ON c.createtime = d.mm LEFT JOIN workday e ON d.mm = e.mm
    WHERE c.createtime >= '2023-09-01'かつ c.endtime < '2023-10-01'
    GROUP BY c.userid、c.type_name、c.type_code;
警告: 未使用のヒント: Leading(c e)
                                                                                 クエリプラン
-------------------------------------------------- -------------------------------------------------- -------------------------------------------------- ------------------------
  ID |操作 | E行 | Eメモリー | E幅 |電子コスト
 ----+------------------------------------------ -------------+--------+----------+----------+-------- --
   1 | ->行アダプター | 2 | | 1502 | 47.97
   2 | ->ベクトルソニックハッシュ集合体 | 2 | | 1502 | 47.97
   3 | ->ベクターストリーミング(種類:GATHER) | 4 | | 1502 | 47.97
   4 | ->ベクトルソニックハッシュ集合体 | 4 | 16MB | 1502 | 41.97
   5 | ->ベクトル ネスト ループの左結合 (6, 7) | 5 | 1MB | 1494 | 41.93
   6 | -> C 作業項目 c にスキャンを保存する | 5 | 1MB | 1502 | 13.08
   7 | ->ベクトルマテリアライズ | 40 | 16MB | 8 | 28.00
   8 | ->ベクターストリーミング(種類:ブロードキャスト) | 40 | 2MB | 8 | 27.90
   9 | ->ベクトル ハッシュ左結合 (10, 11) | 20 | 16MB | 8 | 26.32
  10 | -> C 平日にスキャンを保存する | 20 | 1MB | 8 | 13.01
  11 | -> Cストア スキャンを平日に行う | 20 | 1MB | 8 | 13.01

                                                               述語情報 (プラン ID によって識別される)
 -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- --------------------
   5 -- ベクトル ネスト ループの左結合 (6, 7)
         結合フィルター: (c.createtime = d.mm)
   6 --CStore 作業項目 c のスキャン
         フィルター: ((createtime >= '2023-09-01 00:00:00'::タイムゾーンなしのタイムスタンプ) AND (endtime < '2023-10-01 00:00: 00'::タイムゾーンなしのタイムスタンプ))
         プッシュダウン述語フィルター: ((createtime >= '2023-09-01 00:00:00'::timestamp without timezone) AND (endtime < '2023-10-01 00: 00:00'::タイムゾーンなしのタイムスタンプ))
   9 -- ベクトル ハッシュ左結合 (10, 11)
         ハッシュ条件: (d.mm = e.mm)

   ====== クエリの概要 =====
 -----------------------------
 システム利用可能メモリ: 4710400KB
 クエリ最大メモリ: 4710400KB
 クエリの推定メモリ: 5274KB
(29行)

クエリ文のfromテーブル数がfrom_collapse_limitを超えているか、結合テーブル数がjoin_collapse_limitを超えているかを確認してください。それを超えると一定確率でヒントが発動しなくなります。

デフォルトより小さい値を指定すると、計画時間は短縮されますが、実行計画が不十分になる可能性があります。

postgres=# from_collapse_limit を表示;
 from_collapse_limit
---------------------
 8
(1行)

postgres=# show join_collapse_limit;
 join_collapse_limit
---------------------
 8
(1行)

クエリ ステートメント内の from テーブルの数が geqo_threshold を超えているかどうかを確認します (geqo が有効な場合)。超えている場合は、遺伝的クエリの最適化を使用してプランが生成され、ヒントが有効にならない可能性が高くなります。

単純なクエリの場合は、通常、網羅的な検索方法が使用されますが、複数のテーブルを含むクエリが使用される場合、GEQO を使用するとクエリをより適切に管理できます。

postgres=# geqo_threshold を表示;
 geqo_threshold
----------------
 12
(1行)

クリックしてフォローし、できるだけ早くHuawei Cloudの新しいテクノロジーについて学びましょう~

SenseTime 創設者、Tang Xiaoou 氏が 55 歳で死去 2023 年、PHP は停滞 Wi-Fi 7 が完全に利用可能になる2024 年初頭にデビュー、Wi-Fi 6 の 5 倍高速 Hongmeng システムが独立しつつあり、多くの大学が「Hongmeng クラス」を設立 Zhihui Jun の新興企業が借り換え、金額は 6 億元を超え、事前評価額は 35 億元 Quark Browser PC 版が内部テストを開始 AI コード アシスタントは人気があり、プログラミング言語のランキングはすべてです できることは何もありません Mate 60 Pro の 5G モデムと無線周波数技術ははるかに先を行っています MariaDB が SkySQL を分割し、確立されました独立した企業として<​​/span> Xiaomi、Yu Chengdong 氏の Huawei からの「キールピボット」盗作声明に対応
{{名前}}
{{名前}}

おすすめ

転載: my.oschina.net/u/4526289/blog/10322251