EXPLAIN

EXPLAIN

문장을 실행하지 않고 논리적·분산 실행 계획을 보여주거나 그 문장을 검증할 때 쓰는 명령어예요. 쿼리가 어떤 단계로 실행될지 미리 들여다보고 싶을 때 유용해요.

출처: 문서

본문

Synopsis

EXPLAIN [ ( option [, ...] ) ] statement

이때 option은 다음 중 하나일 수 있어요:

FORMAT { TEXT | GRAPHVIZ | JSON }
TYPE { LOGICAL | DISTRIBUTED | VALIDATE | IO }

Description

문장의 논리적 또는 분산 실행 계획을 보여주거나, 문장을 검증해요.

기본적으로 분산 계획이 표시돼요. 분산 계획의 각 계획 프래그먼트(fragment)는 단일 또는 여러 Trino 노드에서 실행돼요. 프래그먼트의 분리는 Trino 노드 간의 데이터 교환을 나타내요. 프래그먼트 타입은 프래그먼트가 Trino 노드에서 어떻게 실행되고 데이터가 프래그먼트 사이에 어떻게 분산되는지를 지정해요:

  • SINGLE - 프래그먼트가 단일 노드에서 실행돼요.
  • HASH - 프래그먼트가 입력 데이터를 해시 함수로 분산해 고정된 수의 노드에서 실행돼요.
  • ROUND_ROBIN - 프래그먼트가 입력 데이터를 라운드로빈 방식으로 분산해 고정된 수의 노드에서 실행돼요.
  • BROADCAST - 프래그먼트가 입력 데이터를 모든 노드에 브로드캐스트해 고정된 수의 노드에서 실행돼요.
  • SOURCE - 프래그먼트가 입력 스플릿(split)에 접근하는 노드에서 실행돼요.

EXPLAIN (TYPE LOGICAL)

Warning

EXPLAIN (TYPE LOGICAL)은 더 이상 사용되지 않으며(deprecated) 향후 릴리스에서 제거될 예정이에요. 대신 EXPLAIN (TYPE DISTRIBUTED)을 사용하세요.

제공된 쿼리 문장을 처리해 논리적 계획을 텍스트 형식으로 만들어요:

EXPLAIN (TYPE LOGICAL) SELECT regionkey, count(*) FROM nation GROUP BY 1;
                                                   Query Plan
-----------------------------------------------------------------------------------------------------------------
 Trino version: version
 Output[regionkey, _col1]
 │   Layout: [regionkey:bigint, count:bigint]
 │   Estimates: {rows: ? (?), cpu: ?, memory: ?, network: ?}
 │   _col1 := count
 └─ RemoteExchange[GATHER]
    │   Layout: [regionkey:bigint, count:bigint]
    │   Estimates: {rows: ? (?), cpu: ?, memory: ?, network: ?}
    └─ Aggregate(FINAL)[regionkey]
       │   Layout: [regionkey:bigint, count:bigint]
       │   Estimates: {rows: ? (?), cpu: ?, memory: ?, network: ?}
       │   count := count("count_8")
       └─ LocalExchange[HASH][$hashvalue] ("regionkey")
          │   Layout: [regionkey:bigint, count_8:bigint, $hashvalue:bigint]
          │   Estimates: {rows: ? (?), cpu: ?, memory: ?, network: ?}
          └─ RemoteExchange[REPARTITION][$hashvalue_9]
             │   Layout: [regionkey:bigint, count_8:bigint, $hashvalue_9:bigint]
             │   Estimates: {rows: ? (?), cpu: ?, memory: ?, network: ?}
             └─ Project[]
                │   Layout: [regionkey:bigint, count_8:bigint, $hashvalue_10:bigint]
                │   Estimates: {rows: ? (?), cpu: ?, memory: ?, network: ?}
                │   $hashvalue_10 := "combine_hash"(bigint '0', COALESCE("$operator$hash_code"("regionkey"), 0))
                └─ Aggregate(PARTIAL)[regionkey]
                   │   Layout: [regionkey:bigint, count_8:bigint]
                   │   count_8 := count(*)
                   └─ TableScan[tpch:nation:sf0.01]
                          Layout: [regionkey:bigint]
                          Estimates: {rows: 25 (225B), cpu: 225, memory: 0B, network: 0B}
                          regionkey := tpch:regionkey

EXPLAIN (TYPE LOGICAL, FORMAT JSON)

Warning

출력 형식은 Trino 버전 간에 하위 호환성을 보장하지 않아요.

Warning

EXPLAIN (TYPE LOGICAL)은 더 이상 사용되지 않으며 향후 릴리스에서 제거될 예정이에요. 대신 EXPLAIN (TYPE DISTRIBUTED)을 사용하세요.

제공된 쿼리 문장을 처리해 논리적 계획을 JSON 형식으로 만들어요:

EXPLAIN (TYPE LOGICAL, FORMAT JSON) SELECT regionkey, count(*) FROM nation GROUP BY 1;
{
   "id": "9",
   "name": "Output",
   "descriptor": {
      "columnNames": "[regionkey, _col1]"
   },
   "outputs": [
      {
         "symbol": "regionkey",
         "type": "bigint"
      },
      {
         "symbol": "count",
         "type": "bigint"
      }
   ],
   "details": [
      "_col1 := count"
   ],
   "estimates": [
      {
         "outputRowCount": "NaN",
         "outputSizeInBytes": "NaN",
         "cpuCost": "NaN",
         "memoryCost": "NaN",
         "networkCost": "NaN"
      }
   ],
   "children": [
      {
         "id": "145",
         "name": "RemoteExchange",
         "descriptor": {
            "type": "GATHER",
            "isReplicateNullsAndAny": "",
            "hashColumn": ""
         },
         "outputs": [
            {
               "symbol": "regionkey",
               "type": "bigint"
            },
            {
               "symbol": "count",
               "type": "bigint"
            }
         ],
         "details": [

         ],
         "estimates": [
            {
               "outputRowCount": "NaN",
               "outputSizeInBytes": "NaN",
               "cpuCost": "NaN",
               "memoryCost": "NaN",
               "networkCost": "NaN"
            }
         ],
         "children": [
            {
               "id": "4",
               "name": "Aggregate",
               "descriptor": {
                  "type": "FINAL",
                  "keys": "[regionkey]",
                  "hash": ""
               },
               "outputs": [
                  {
                     "symbol": "regionkey",
                     "type": "bigint"
                  },
                  {
                     "symbol": "count",
                     "type": "bigint"
                  }
               ],
               "details": [
                  "count := count(\"count_0\")"
               ],
               "estimates": [
                  {
                     "outputRowCount": "NaN",
                     "outputSizeInBytes": "NaN",
                     "cpuCost": "NaN",
                     "memoryCost": "NaN",
                     "networkCost": "NaN"
                  }
               ],
               "children": [
                  {
                     "id": "194",
                     "name": "LocalExchange",
                     "descriptor": {
                        "partitioning": "HASH",
                        "isReplicateNullsAndAny": "",
                        "hashColumn": "[$hashvalue]",
                        "arguments": "[\"regionkey\"]"
                     },
                     "outputs": [
                        {
                           "symbol": "regionkey",
                           "type": "bigint"
                        },
                        {
                           "symbol": "count_0",
                           "type": "bigint"
                        },
                        {
                           "symbol": "$hashvalue",
                           "type": "bigint"
                        }
                     ],
                     "details":[],
                     "estimates": [
                        {
                           "outputRowCount": "NaN",
                           "outputSizeInBytes": "NaN",
                           "cpuCost": "NaN",
                           "memoryCost": "NaN",
                           "networkCost": "NaN"
                        }
                     ],
                     "children": [
                        {
                           "id": "200",
                           "name": "RemoteExchange",
                           "descriptor": {
                              "type": "REPARTITION",
                              "isReplicateNullsAndAny": "",
                              "hashColumn": "[$hashvalue_1]"
                           },
                           "outputs": [
                              {
                                 "symbol": "regionkey",
                                 "type": "bigint"
                              },
                              {
                                 "symbol": "count_0",
                                 "type": "bigint"
                              },
                              {
                                 "symbol": "$hashvalue_1",
                                 "type": "bigint"
                              }
                           ],
                           "details":[],
                           "estimates": [
                              {
                                 "outputRowCount": "NaN",
                                 "outputSizeInBytes": "NaN",
                                 "cpuCost": "NaN",
                                 "memoryCost": "NaN",
                                 "networkCost": "NaN"
                              }
                           ],
                           "children": [
                              {
                                 "id": "226",
                                 "name": "Project",
                                 "descriptor": {},
                                 "outputs": [
                                    {
                                       "symbol": "regionkey",
                                       "type": "bigint"
                                    },
                                    {
                                       "symbol": "count_0",
                                       "type": "bigint"
                                    },
                                    {
                                       "symbol": "$hashvalue_2",
                                       "type": "bigint"
                                    }
                                 ],
                                 "details": [
                                    "$hashvalue_2 := combine_hash(bigint '0', COALESCE(\"$operator$hash_code\"(\"regionkey\"), 0))"
                                 ],
                                 "estimates": [
                                    {
                                       "outputRowCount": "NaN",
                                       "outputSizeInBytes": "NaN",
                                       "cpuCost": "NaN",
                                       "memoryCost": "NaN",
                                       "networkCost": "NaN"
                                    }
                                 ],
                                 "children": [
                                    {
                                       "id": "198",
                                       "name": "Aggregate",
                                       "descriptor": {
                                          "type": "PARTIAL",
                                          "keys": "[regionkey]",
                                          "hash": ""
                                       },
                                       "outputs": [
                                          {
                                             "symbol": "regionkey",
                                             "type": "bigint"
                                          },
                                          {
                                             "symbol": "count_0",
                                             "type": "bigint"
                                          }
                                       ],
                                       "details": [
                                          "count_0 := count(*)"
                                       ],
                                       "estimates":[],
                                       "children": [
                                          {
                                             "id": "0",
                                             "name": "TableScan",
                                             "descriptor": {
                                                "table": "hive:tpch_sf1_orc_part:nation"
                                             },
                                             "outputs": [
                                                {
                                                   "symbol": "regionkey",
                                                   "type": "bigint"
                                                }
                                             ],
                                             "details": [
                                                "regionkey := regionkey:bigint:REGULAR"
                                             ],
                                             "estimates": [
                                                {
                                                   "outputRowCount": 25,
                                                   "outputSizeInBytes": 225,
                                                   "cpuCost": 225,
                                                   "memoryCost": 0,
                                                   "networkCost": 0
                                                }
                                             ],
                                             "children": []
                                          }
                                       ]
                                    }
                                 ]
                              }
                           ]
                        }
                     ]
                  }
               ]
            }
         ]
      }
   ]
}

EXPLAIN (TYPE DISTRIBUTED)

제공된 쿼리 문장을 처리해 분산 계획을 텍스트 형식으로 만들어요. 분산 계획은 논리적 계획을 스테이지로 나누므로 워커 사이의 데이터 교환을 명시적으로 보여줘요:

EXPLAIN (TYPE DISTRIBUTED) SELECT regionkey, count(*) FROM nation GROUP BY 1;
                                              Query Plan
------------------------------------------------------------------------------------------------------
 Trino version: version
 Fragment 0 [SINGLE]
     Output layout: [regionkey, count]
     Output partitioning: SINGLE []
     Output[regionkey, _col1]
     │   Layout: [regionkey:bigint, count:bigint]
     │   Estimates: {rows: ? (?), cpu: ?, memory: ?, network: ?}
     │   _col1 := count
     └─ RemoteSource[1]
            Layout: [regionkey:bigint, count:bigint]

 Fragment 1 [HASH]
     Output layout: [regionkey, count]
     Output partitioning: SINGLE []
     Aggregate(FINAL)[regionkey]
     │   Layout: [regionkey:bigint, count:bigint]
     │   Estimates: {rows: ? (?), cpu: ?, memory: ?, network: ?}
     │   count := count("count_8")
     └─ LocalExchange[HASH][$hashvalue] ("regionkey")
        │   Layout: [regionkey:bigint, count_8:bigint, $hashvalue:bigint]
        │   Estimates: {rows: ? (?), cpu: ?, memory: ?, network: ?}
        └─ RemoteSource[2]
               Layout: [regionkey:bigint, count_8:bigint, $hashvalue_9:bigint]

 Fragment 2 [SOURCE]
     Output layout: [regionkey, count_8, $hashvalue_10]
     Output partitioning: HASH [regionkey][$hashvalue_10]
     Project[]
     │   Layout: [regionkey:bigint, count_8:bigint, $hashvalue_10:bigint]
     │   Estimates: {rows: ? (?), cpu: ?, memory: ?, network: ?}
     │   $hashvalue_10 := "combine_hash"(bigint '0', COALESCE("$operator$hash_code"("regionkey"), 0))
     └─ Aggregate(PARTIAL)[regionkey]
        │   Layout: [regionkey:bigint, count_8:bigint]
        │   count_8 := count(*)
        └─ TableScan[tpch:nation:sf0.01, grouped = false]
               Layout: [regionkey:bigint]
               Estimates: {rows: 25 (225B), cpu: 225, memory: 0B, network: 0B}
               regionkey := tpch:regionkey

EXPLAIN (TYPE DISTRIBUTED, FORMAT JSON)

Warning

출력 형식은 Trino 버전 간에 하위 호환성을 보장하지 않아요.

제공된 쿼리 문장을 처리해 분산 계획을 JSON 형식으로 만들어요. 분산 계획은 논리적 계획을 스테이지로 나누므로 워커 사이의 데이터 교환을 명시적으로 보여줘요:

EXPLAIN (TYPE DISTRIBUTED, FORMAT JSON) SELECT regionkey, count(*) FROM nation GROUP BY 1;
{
   "0" : {
      "id" : "9",
      "name" : "Output",
      "descriptor" : {
         "columnNames" : "[regionkey, _col1]"
      },
      "outputs" : [ {
         "symbol" : "regionkey",
         "type" : "bigint"
      }, {
         "symbol" : "count",
         "type" : "bigint"
      } ],
      "details" : [ "_col1 := count" ],
      "estimates" : [ {
         "outputRowCount" : "NaN",
         "outputSizeInBytes" : "NaN",
         "cpuCost" : "NaN",
         "memoryCost" : "NaN",
         "networkCost" : "NaN"
      } ],
      "children" : [ {
         "id" : "145",
         "name" : "RemoteSource",
         "descriptor" : {
            "sourceFragmentIds" : "[1]"
         },
         "outputs" : [ {
            "symbol" : "regionkey",
            "type" : "bigint"
         }, {
            "symbol" : "count",
            "type" : "bigint"
         } ],
         "details" : [ ],
         "estimates" : [ ],
         "children" : [ ]
      } ]
   },
   "1" : {
      "id" : "4",
      "name" : "Aggregate",
      "descriptor" : {
         "type" : "FINAL",
         "keys" : "[regionkey]",
         "hash" : "[]"
      },
      "outputs" : [ {
         "symbol" : "regionkey",
         "type" : "bigint"
      }, {
         "symbol" : "count",
         "type" : "bigint"
      } ],
      "details" : [ "count := count(\"count_0\")" ],
      "estimates" : [ {
         "outputRowCount" : "NaN",
         "outputSizeInBytes" : "NaN",
         "cpuCost" : "NaN",
         "memoryCost" : "NaN",
         "networkCost" : "NaN"
      } ],
      "children" : [ {
         "id" : "194",
         "name" : "LocalExchange",
         "descriptor" : {
            "partitioning" : "SINGLE",
            "isReplicateNullsAndAny" : "",
            "hashColumn" : "[]",
            "arguments" : "[]"
         },
         "outputs" : [ {
            "symbol" : "regionkey",
            "type" : "bigint"
         }, {
            "symbol" : "count_0",
            "type" : "bigint"
         } ],
         "details" : [ ],
         "estimates" : [ {
            "outputRowCount" : "NaN",
            "outputSizeInBytes" : "NaN",
            "cpuCost" : "NaN",
            "memoryCost" : "NaN",
            "networkCost" : "NaN"
         } ],
         "children" : [ {
            "id" : "227",
            "name" : "Project",
            "descriptor" : { },
            "outputs" : [ {
               "symbol" : "regionkey",
               "type" : "bigint"
            }, {
               "symbol" : "count_0",
               "type" : "bigint"
            } ],
            "details" : [ ],
            "estimates" : [ {
               "outputRowCount" : "NaN",
               "outputSizeInBytes" : "NaN",
               "cpuCost" : "NaN",
               "memoryCost" : "NaN",
               "networkCost" : "NaN"
            } ],
            "children" : [ {
               "id" : "200",
               "name" : "RemoteSource",
               "descriptor" : {
                  "sourceFragmentIds" : "[2]"
               },
               "outputs" : [ {
                  "symbol" : "regionkey",
                  "type" : "bigint"
               }, {
                  "symbol" : "count_0",
                  "type" : "bigint"
               }, {
                  "symbol" : "$hashvalue",
                  "type" : "bigint"
               } ],
               "details" : [ ],
               "estimates" : [ ],
               "children" : [ ]
            } ]
         } ]
      } ]
   },
   "2" : {
      "id" : "226",
      "name" : "Project",
      "descriptor" : { },
      "outputs" : [ {
         "symbol" : "regionkey",
         "type" : "bigint"
      }, {
         "symbol" : "count_0",
         "type" : "bigint"
      }, {
         "symbol" : "$hashvalue_1",
         "type" : "bigint"
      } ],
      "details" : [ "$hashvalue_1 := combine_hash(bigint '0', COALESCE(\"$operator$hash_code\"(\"regionkey\"), 0))" ],
      "estimates" : [ {
         "outputRowCount" : "NaN",
         "outputSizeInBytes" : "NaN",
         "cpuCost" : "NaN",
         "memoryCost" : "NaN",
         "networkCost" : "NaN"
      } ],
      "children" : [ {
         "id" : "198",
         "name" : "Aggregate",
         "descriptor" : {
            "type" : "PARTIAL",
            "keys" : "[regionkey]",
            "hash" : "[]"
         },
         "outputs" : [ {
            "symbol" : "regionkey",
            "type" : "bigint"
         }, {
            "symbol" : "count_0",
            "type" : "bigint"
         } ],
         "details" : [ "count_0 := count(*)" ],
         "estimates" : [ ],
         "children" : [ {
            "id" : "0",
            "name" : "TableScan",
            "descriptor" : {
               "table" : "tpch:tiny:nation"
            },
            "outputs" : [ {
               "symbol" : "regionkey",
               "type" : "bigint"
            } ],
            "details" : [ "regionkey := tpch:regionkey" ],
            "estimates" : [ {
               "outputRowCount" : 25.0,
               "outputSizeInBytes" : 225.0,
               "cpuCost" : 225.0,
               "memoryCost" : 0.0,
               "networkCost" : 0.0
            } ],
            "children" : [ ]
         } ]
      } ]
   }
}

EXPLAIN (TYPE VALIDATE)

제공된 쿼리 문장을 구문적으로·의미적으로 올바른지 검증해요. 문장이 유효하면 true를 반환해요:

EXPLAIN (TYPE VALIDATE) SELECT regionkey, count(*) FROM nation GROUP BY 1;
 Valid
-------
 true

알 수 없는 키워드 같은 구문 오류로 문장이 올바르지 않으면 오류 메시지가 문제를 자세히 설명해요:

EXPLAIN (TYPE VALIDATE) SELET 1=0;
Query 20220929_234840_00001_vjwxj failed: line 1:25: mismatched input 'SELET'.
Expecting: 'ALTER', 'ANALYZE', 'CALL', 'COMMENT', 'COMMIT', 'CREATE',
'DEALLOCATE', 'DELETE', 'DENY', 'DESC', 'DESCRIBE', 'DROP', 'EXECUTE',
'EXPLAIN', 'GRANT', 'INSERT', 'MERGE', 'PREPARE', 'REFRESH', 'RESET',
'REVOKE', 'ROLLBACK', 'SET', 'SHOW', 'START', 'TRUNCATE', 'UPDATE', 'USE',

마찬가지로, 유효하지 않은 객체 이름(예: nation 대신 nations) 같은 의미적 문제가 감지되면 오류 메시지가 유용한 정보를 반환해요:

EXPLAIN(TYPE VALIDATE) SELECT * FROM tpch.tiny.nations;
Query 20220929_235059_00003_vjwxj failed: line 1:15: Table 'tpch.tiny.nations' does not exist
SELECT * FROM tpch.tiny.nations

EXPLAIN (TYPE IO)

제공된 쿼리 문장을 처리해 접근한 객체의 입력·출력 정보를 JSON 형식으로 담은 계획을 만들어요:

EXPLAIN (TYPE IO, FORMAT JSON) INSERT INTO test_lineitem
SELECT * FROM lineitem WHERE shipdate = '2020-02-01' AND quantity > 10;
            Query Plan
-----------------------------------
{
   inputTableColumnInfos: [
      {
         table: {
            catalog: "hive",
            schemaTable: {
               schema: "tpch",
               table: "test_orders"
            }
         },
         columnConstraints: [
            {
               columnName: "orderkey",
               type: "bigint",
               domain: {
                  nullsAllowed: false,
                  ranges: [
                     {
                        low: {
                           value: "1",
                           bound: "EXACTLY"
                        },
                        high: {
                           value: "1",
                           bound: "EXACTLY"
                        }
                     },
                     {
                        low: {
                           value: "2",
                           bound: "EXACTLY"
                        },
                        high: {
                           value: "2",
                           bound: "EXACTLY"
                        }
                     }
                  ]
               }
            },
            {
               columnName: "processing",
               type: "boolean",
               domain: {
                  nullsAllowed: false,
                  ranges: [
                     {
                        low: {
                           value: "false",
                           bound: "EXACTLY"
                        },
                        high: {
                           value: "false",
                           bound: "EXACTLY"
                        }
                     }
                  ]
               }
            },
            {
               columnName: "custkey",
               type: "bigint",
               domain: {
                  nullsAllowed: false,
                  ranges: [
                     {
                        low: {
                           bound: "ABOVE"
                        },
                        high: {
                           value: "10",
                           bound: "EXACTLY"
                        }
                     }
                  ]
               }
            }
         ],
         estimate: {
            outputRowCount: 2,
            outputSizeInBytes: 40,
            cpuCost: 40,
            maxMemory: 0,
            networkCost: 0
         }
      }
   ],
   outputTable: {
      catalog: "hive",
      schemaTable: {
         schema: "tpch",
         table: "test_orders"
      }
   },
   estimate: {
      outputRowCount: "NaN",
      outputSizeInBytes: "NaN",
      cpuCost: "NaN",
      maxMemory: "NaN",
      networkCost: "NaN"
   }
}

See also

EXPLAIN ANALYZE 명령과 함께 사용해요.

더 알아보기 (Learn more)

실제 실행과 함께 각 연산의 비용을 확인하려면 EXPLAIN ANALYZE도 함께 살펴보세요.