Hiveクエリの例: Order By、Group By & Cluster By

⚡ スマートサマリー

Hiveクエリでは、ORDER BY、GROUP BY、SORT BY、CLUSTER BY、DISTRIBUTE BY句を使用して、行をリデューサー間でソート、グループ化、分散します。ここでは、各句を単一のサンプルemployeesテーブルで説明します。

  • 🧱 まずサンプル表から始めます。 employees_guruは6つの列で作成され、どの句が実行される前にEmployees.txtから読み込まれます。
  • 🔢 合計値で並べ替え: ORDER BY句は結果セット全体を1つのリデューサーに送信するため、完全な順序が保証されますが、大規模なクエリの処理速度が低下します。
  • 🔤 文字列のソート: 「部署」などの文字列型の列は、数値順ではなく辞書順で返されます。
  • 📊 GROUP BY カウント: GROUP BYとcount(*)を組み合わせると、部門ごとに1行が返され、その部門の従業員総数が表示されます。
  • 🔀 並べ替え基準はリデューサーごとです。 SORT BY は各リデューサー内の行を順序付けるため、複数のリデューサーは部分的に順序付けられた出力を生成します。
  • 🎯 クラスター化の組み合わせ: CLUSTER BYはDISTRIBUTE BYとSORT BYを組み合わせた機能ですが、DISTRIBUTE BY単独では、一致するキーをソートせずに1つのリデューサーにルーティングします。

HiveクエリのOrder By、Group By、 Cluster および配布元

HiveはETL目的のためにSQLタイプのクエリ言語を提供します。 Hadoopの ファイルシステム。

Hiveクエリ言語(HiveQL)は、Hive内でテーブル、データベース、クエリを操作するためのSQLタイプの環境を提供します。

Hiveには、さまざまな種類のデータ操作やクエリを実行するためのさまざまな種類の句が関連付けられており、Hiveは環境外のノードとの接続を向上させるためにJDBC接続機能を提供します。

Hiveクエリは以下の機能を提供します。

  • データベースやテーブルなどの作成といったデータモデリング。
  • ETL機能の例tracデータの変換、テーブルへのロード
  • ジョイン 異なるデータテーブルをマージするには
  • コードを容易にするユーザー固有のカスタム スクリプト
  • Hadoop 上の高速クエリ ツール

Hive でのテーブルの作成

このチュートリアルのメインテーマに入る前に、まず以降の各セクションで参照するための表を作成します。

このチュートリアルでは、以下のスクリーンショットに示すように、6つの列を持つ「employees_guru」というテーブルを作成します。

employees_guru の Hive CREATE TABLE ステートメントとロードコマンド

上のスクリーンショットから、

  1. 私たちは、「guru」という組織に所属する従業員に関する、ID、名前、年齢、住所、給与、部署の6つの列の値を持つテーブル「employees_guru」を作成します。
  2. このステップでは、employees_guruテーブルにデータをロードします。ロードするデータは、Employees.txtファイルに格納されています。

クエリによる注文

HiveQL の ORDER BY 構文は、 SQL 言語。

ORDER BY は「SELECT」ステートメントで使用する句です。 ハイブクエリ データをソートします。Hiveテーブルの列を使用して、ORDER BYで指定された特定の列の値をソートし、クエリはそれらの値の昇順または降順で結果を表示します。

指定された ORDER BY フィールドが文字列の場合、結果は辞書順に表示されます。バックエンドでは、結果セット全体を単一のリデューサーに渡す必要があります。

その単一のリデューサーは、大きなテーブルでの ORDER BY をコストのかかるものにするため、厳密モードでは (hive.mapred.mode=strict) Hive は LIMIT 句を含まない ORDER BY を拒否します。

以下のスクリーンショットは、ORDER BYクエリとそのソートされた行を示しています。

従業員_guru を部門別にソートしたクエリ

上記のスクリーンショットから、以下のことが確認できます。

  1. これは、「employees_guru」テーブルに対してORDER BY句と、定義されたORDER BY列名としてDepartmentを指定して実行されたクエリです。「Department」は文字列であるため、結果は辞書順に表示されます。
  2. これはクエリの実際の出力です。結果は「部門」列に基づいて、管理部門、財務部門など、順番に表示されます。

クエリ:

SELECT * FROM employees_guru ORDER BY Department;

クエリごとにグループ化する

GROUP BY句は、Hiveテーブルの列をグループ化に使用します。ping GROUP BY句で指定された特定の列の値に基づいてクエリが実行され、それらの値でグループ化された結果が選択されて表示されます。

例えば、以下のスクリーンショットは、各部署に所属する従業員の総数を示しています。ここでは、「部署」をグループ化の値として使用しています。

各部門の従業員数をカウントするGROUP BYクエリ

上記のスクリーンショットから、以下の点が確認できます。

  1. これは、「employees_guru」テーブルに対して、GROUP BY句と、定義されたGROUP BY列名としてDepartmentを指定して実行されるクエリです。
  2. ここに表示されている出力は、各部署の部署名と従業員数です。特定の部署に所属するすべての従業員がグループ化されて表示されるため、各結果行は部署名とその部署の従業員総数となります。

クエリ:

SELECT Department, count(*) FROM employees_guru GROUP BY Department;

並べ替え

SORT BY句は、Hiveテーブルの列名に基づいて出力をソートします。降順でソートする場合はDESC、昇順でソートする場合はASCを指定できます。

SORT BY は、行をリデューサーに渡す前にソートするため、結果全体ではなく、各リデューサー内で順序が保証されます。ソートは常に列の型に依存します。

例えば、列の型が数値であれば数値順にソートされ、列の型が文字列であれば辞書順にソートされます。

以下のスクリーンショットは、降順(DESC)を使用したSORT BYクエリを示しています。

employees_guru に対する SORT BY クエリは、ID を降順で返します。

上記のスクリーンショットから、次のことがわかります。

  1. これは、SORT BY句と定義されたSORT BY列名「Id」を使用して、「employees_guru」テーブルに対して実行されたクエリです。キーワードDESCを使用しました。
  2. したがって、表示される出力は「Id」の降順になります。

クエリ:

SELECT * from employees_guru SORT BY Id DESC;

Cluster By

HiveQLでは、CLUSTER BYはDISTRIBUTE BY句とSORT BY句の両方の代替として使用されます。

Hive のテーブルでは、CLUSTER BY 句が使用されます。Hive は CLUSTER BY 句で指定された列を使用して、行をリデューサー間で分散します。CLUSTER BY 句で指定された列は複数のリデューサーに渡されます。また、複数のリデューサーに存在する値のソート順も保証されます。

例えば、employees_guruテーブルのId列名にCLUSTER BY句が指定されています。このクエリを実行すると、バックエンドでは複数のリデューサーに結果が渡されますが、フロントエンドではSORT BYとDISTRIBUTE BYの両方の代替句として機能します。

これは、MapReduceフレームワークにおいて、SORT BY、GROUP BY、またはCLUSTER BYを使用してクエリを実行する際のバックエンド処理です。したがって、結果を複数のリデューサーに格納したい場合は、CLUSTER BYを使用します。

CLUSTER BY構文は列名のみを受け付けるため、ASCとDESCを付加することはできません。降順の結果を得るには、DISTRIBUTE BYとSORT BY … DESCを別途指定する必要があります。

以下のスクリーンショットは、Id に対する CLUSTER BY クエリを示しています。

employees_guru の Id 列に対する CLUSTER BY クエリ

上記のスクリーンショットから、次のことがわかります。

  1. これは、IDフィールドの値に対してCLUSTER BY句を実行するクエリです。ここでは、ID値に基づいてソートが行われます。
  2. employees_guru に存在する Id と Name の値をソートされた順序で表示します。

クエリ:

SELECT  Id, Name from employees_guru CLUSTER BY Id;

配布者

Hive のテーブルでは、DISTRIBUTE BY 句が使用されます。Hive は DISTRIBUTE BY 句の列を使用して行をリデューサーに分散するため、同じ DISTRIBUTE BY 列の値を持つすべての行は同じリデューサーに送られます。

  • これにより、N 個のリデューサーそれぞれが重複のない信号を受け取ることが保証されます。ping 列の値のセット
  • 各リデューサーの出力はソートされず、一致する行が必ずしも隣り合うとは限りません。

以下のスクリーンショットは、ID に対する DISTRIBUTE BY クエリを示しています。

employees_guru の Id 列に対する DISTRIBUTE BY クエリ

上記のスクリーンショットから、以下のことが分かります。

  1. DISTRIBUTE BY句は、「employees_guru」テーブルのIDに対して実行されます。
  2. 出力にはIDと名前が表示されます。バックエンドでは、同じIDを持つ行は同じリデューサーに送られます。

クエリ:

SELECT  Id, Name from employees_guru DISTRIBUTE BY Id;

これら4つの条項は混同しやすいので、以下の表で比較します。

句 レデューサー それが保証するもの
ORDER BY 1 結果全体にわたる総順序
SORT B​​Y その他にもたくさんのグーグルの 各減速機内での注文のみ
配布元 その他にもたくさんのグーグルの 同じキーが同じリデューサーに到達し、ソートされない
クラスター別 その他にもたくさんのグーグルの 分配基準と昇順による並べ替え

よくあるご質問

単一のリデューサーがすべての行をソートする必要があり、大きなテーブルでは数時間かかる場合があります。有効な制限範囲を制限してください。hive.mapred.mode を nonstrict に設定すると、この制限が完全に解除されます。

クエリの前に mapreduce.job.reduces を設定してカウントを固定してください。設定しない場合、Hive は入力サイズからカウントを推定します。ORDER BY ではこの設定は無視されます。なぜなら、トータルオーダーは常に 1 つのリデューサーに集約されるからです。

いいえ。この句は列名のみを受け付け、常に昇順でソートします。代わりに、パーティション列に対して DISTRIBUTE BY 句を記述し、別の SORT BY 列として DESC を指定してください。この 2 つの列は異なっていても構いません。

両者は関連しているが、同一ではない。 バケット は行を固定数のファイルに永続的に保存するのに対し、CLUSTER BY は行を 1 つのクエリの実行期間中のみ分散およびソートします。

機械学習アシスタントはEXPLAINプランを読み取り、ORDER BY句の制限超過、パーティションフィルタの欠落、キーの偏りなどの原因を特定します。すべての提案は実際の実行時と照合して確認してください。

短いコメントからこれらのパターンをうまく作成します。エンジン固有のものは何でも確認してください。 Spark Hiveが拒否するSQLまたはPresto構文(CLUSTER BYの後にDESCなど)。

Employees.txtという名前のプレーンテキストファイルには6つの列の値が格納されており、最初のクエリが実行される前にテーブルに読み込まれます。対応する列を持つ区切り文字付きファイルであれば、同様に機能します。

これらはHiveQL言語の機能であってエンジンの機能ではないため、意味論は同じです。物理的な実行計画のみが変わります。エンジンはソートとシャッフルのステージを異なる方法でスケジュールするため、実行時間は異なりますが、結果は変わりません。