Looker 中的派生表

在 Looker 中,派生表是一种查询,其结果的使用方式就像是数据库中的实际表一样。

例如,您可能有一个名为 orders 的数据库表,其中包含许多列。您想要计算一些客户级汇总指标,例如每个客户下了多少个订单,或每个客户首次下单的时间。您可以使用原生派生表基于 SQL 的派生表,创建一个名为 customer_order_summary 的新数据库表,其中包含这些指标。

然后,您可以像使用数据库中的任何其他表一样使用 customer_order_summary 派生表。

如需了解派生表的常见用例,请参阅 Looker 食谱:充分利用 Looker 中的派生表

原生派生表和基于 SQL 的派生表

如需在 Looker 项目中创建派生表,请在 view 参数下使用 derived_table 参数。在 derived_table 参数中,您可以通过以下两种方式之一定义派生表的查询:

例如,以下视图文件展示了如何使用 LookML 从 customer_order_summary 派生表创建视图。下面两个版本的 LookML 展示了如何使用 LookML 或 SQL 来定义派生表的查询,从而创建等效的派生表:

  • 原生派生表在 explore_source 参数中使用 LookML 定义查询。在此示例中,查询基于现有的 orders 视图,该视图在本示例中未显示的单独文件中定义。原生派生表中的 explore_source 查询会从 orders 视图文件中引入 customer_idfirst_ordertotal_amount 字段。
  • 基于 SQL 的派生表在 sql 参数中使用 SQL 定义查询。在此示例中,SQL 查询是对数据库中 orders 表的直接查询。
原生派生表版本
view: customer_order_summary {
  derived_table: {
    explore_source: orders {
      column: customer_id {
        field: orders.customer_id
      }
      column: first_order {
        field: orders.first_order
      }
      column: total_amount {
        field: orders.total_amount
      }
    }
  }
  dimension: customer_id {
    type: number
    primary_key: yes
    sql: ${TABLE}.customer_id ;;
  }
  dimension_group: first_order {
    type: time
    timeframes: [date, week, month]
    sql: ${TABLE}.first_order ;;
  }
  dimension: total_amount {
    type: number
    value_format: "0.00"
    sql: ${TABLE}.total_amount ;;
  }
}
基于 SQL 的派生表版本
view: customer_order_summary {
  derived_table: {
    sql:
      SELECT
        customer_id,
        MIN(DATE(time)) AS first_order,
        SUM(amount) AS total_amount
      FROM
        orders
      GROUP BY
        customer_id ;;
  }
  dimension: customer_id {
    type: number
    primary_key: yes
    sql: ${TABLE}.customer_id ;;
  }
  dimension_group: first_order {
    type: time
    timeframes: [date, week, month]
    sql: ${TABLE}.first_order ;;
  }
  dimension: total_amount {
    type: number
    value_format: "0.00"
    sql: ${TABLE}.total_amount ;;
  }
}

这两个版本都会创建一个名为 customer_order_summary 的视图,该视图基于 orders 表,包含 customer_idfirst_order,total_amount 列。

除了 derived_table 参数及其子参数之外,此 customer_order_summary 视图的运作方式与任何其他视图文件一样。无论您是使用 LookML 还是 SQL 定义派生表的查询,都可以根据派生表的列创建 LookML 测量和维度。

定义派生表后,您可以像使用数据库中的任何其他表一样使用它。

原生派生表

原生派生表基于您使用 LookML 术语定义的查询。如需创建原生派生表,您可以在视图参数的 derived_table 参数内使用 explore_source 参数。您可以通过引用模型中的 LookML 维度或测量来创建原生派生表的列。请参阅上一个示例中的原生派生表格视图文件。

与基于 SQL 的派生表相比,在对数据进行建模时,原生派生表更易于阅读和理解。

如需详细了解如何创建原生派生表,请参阅创建原生派生表文档页面。

基于 SQL 的派生表

如需创建基于 SQL 的派生表,您需要使用 SQL 术语定义查询,并使用 SQL 查询在表中创建列。您无法在基于 SQL 的派生表中引用 LookML 维度和测量。请参阅上例中的基于 SQL 的派生表视图文件。

最常见的是,您可以使用视图参数的 derived_table 参数中的 sql 参数来定义 SQL 查询。

在 Looker 中创建基于 SQL 的查询时,一个实用的快捷方式是使用 SQL Runner 创建 SQL 查询并将其转换为派生表定义

在某些极端情况下,系统不允许使用 sql 参数。在这种情况下,Looker 支持使用以下参数为永久派生表 (PDT) 定义 SQL 查询:

  • create_process:为 PDT 使用 sql 参数时,Looker 会在后台将方言的 CREATE TABLE 数据定义语言 (DDL) 语句封装在查询中,以便根据 SQL 查询创建 PDT。某些方言不支持单步执行 SQL CREATE TABLE 语句。对于这些方言,您无法使用 sql 参数创建 PDT。不过,您可以使用 create_process 参数分步创建 PDT。如需了解相关信息和示例,请参阅 create_process 参数文档页面。
  • sql_create:如果您的用例需要自定义 DDL 命令,并且您的方言支持 DDL(例如 Google 预测性 BigQuery ML),您可以使用 sql_create 参数创建 PDT,而不是使用 sql 参数。如需了解相关信息和示例,请参阅 sql_create 文档页面。

无论您使用的是 sqlcreate_process 还是 sql_create 参数,在所有这些情况下,您都是使用 SQL 查询定义派生表,因此这些派生表都属于基于 SQL 的派生表。

定义基于 SQL 的派生表时,请务必使用 AS 为每个列提供简洁的别名。这是因为您需要在维度(例如 ${TABLE}.first_order)中引用结果集的列名称。这就是为什么上例使用 MIN(DATE(time)) AS first_order 而非仅使用 MIN(DATE(time)) 的原因。

临时派生表和永久性派生表

除了原生派生表和基于 SQL 的派生表之间的区别之外,临时派生表(不会写入数据库)与永久性派生表 (PDT) 之间也有区别,后者会写入数据库中的架构。

原生派生表和基于 SQL 的派生表可以是临时表,也可以是永久表。

临时派生表

之前显示的派生表临时派生表的示例。它们是临时的,因为 derived_table 参数中未定义任何持久化策略

临时派生表不会写入数据库。当用户运行涉及一个或多个派生表的探索查询时,Looker 会使用派生表的 SQL 以及请求的字段、联接和过滤值的方言专用组合来构建 SQL 查询。如果组合之前已运行,并且结果在缓存中仍然有效,Looker 会使用缓存的结果。如需详细了解 Looker 中的查询缓存,请参阅缓存查询文档页面。

否则,如果 Looker 无法使用缓存结果,则每当用户请求从临时派生表中获取数据时,Looker 都必须对您的数据库运行新查询。因此,您应确保临时派生表的性能良好,并且不会给数据库带来过多压力。如果查询需要一些时间才能运行,PDT 通常是更好的选择。

临时派生表支持的数据库方言

为了让 Looker 支持 Looker 项目中的派生表,您的数据库方言也必须支持派生表。下表显示了最新版 Looker 中支持派生表的方言:

方言 是否支持?
Actian Avalanche
Amazon Athena
Amazon Aurora MySQL
Amazon Redshift
Apache Druid
Apache Druid 0.13+
Apache Druid 0.18 及更高版本
Apache Hive 2.3 及更高版本
Apache Hive 3.1.2 及更高版本
Apache Spark 3 及更高版本
ClickHouse
Cloudera Impala 3.1 及更高版本
搭配原生驱动程序的 Cloudera Impala 3.1 及更高版本
使用原生驱动程序的 Cloudera Impala
DataVirtuality
Databricks
Denodo 7
Denodo 8
Dremio
Dremio 11+
Exasol
Firebolt
Google BigQuery 旧版 SQL
Google BigQuery 标准 SQL
Google Cloud PostgreSQL
Google Cloud SQL
Google Spanner
Greenplum
HyperSQL
IBM Netezza
MariaDB
Microsoft Azure PostgreSQL
Microsoft Azure SQL Database
Microsoft Azure Synapse Analytics
Microsoft SQL Server 2008 及更高版本
Microsoft SQL Server 2012 及更高版本
Microsoft SQL Server 2016
Microsoft SQL Server 2017 及更高版本
MongoBI
MySQL
MySQL 8.0.12 及更高版本
Oracle
Oracle ADWC
PostgreSQL 9.5 及更高版本
9.5 之前的 PostgreSQL
PrestoDB
PrestoSQL
SAP HANA 2+
SingleStore
SingleStore 7+
Snowflake
TeraData
Trino
向量
Vertica

永久性派生表

永久性派生表 (PDT) 是一种会写入数据库中的临时架构,并根据您使用持久性策略指定的时间表进行重新生成的派生表。

PDT 可以是原生派生表基于 SQL 的派生表

对 PDT 的要求

如需在 Looker 项目中使用永久性派生表 (PDT),您需要满足以下条件:

  • 支持 PDT 的数据库方言。如需查看支持基于 SQL 的永久性派生表永久性原生派生表的方言列表,请参阅本页下文中的适用于 PDT 的数据库方言部分。
  • 数据库中的测试架构。这可以是数据库中的任何架构,但我们建议您创建一个仅用于此目的的新架构。数据库管理员必须为 Looker 数据库用户配置具有写入权限的架构。

  • Looker 连接,其启用 PDT 切换开关处于开启状态。这通常是在您初始配置 Looker 连接时设置的(如需了解数据库方言的说明,请参阅 Looker 方言文档页面),但您也可以在初始设置后为连接启用 PDT。

PDT 支持的数据库方言

为了让 Looker 支持 Looker 项目中的永久性派生表 (PDT),您的数据库方言也必须支持它们。

如需支持任何类型的 PDT(基于 LookML 或基于 SQL),方言必须支持对数据库进行写入,以及满足其他要求。某些只读数据库配置不允许持久化(最常见的是 Postgres 热插拔副本数据库)。在这些情况下,您可以改用临时派生表

下表显示了最新版 Looker 中支持基于 SQL 的永久性派生表的方言:

方言 是否支持?
Actian Avalanche
Amazon Athena
Amazon Aurora MySQL
Amazon Redshift
Apache Druid
Apache Druid 0.13+
Apache Druid 0.18 及更高版本
Apache Hive 2.3 及更高版本
Apache Hive 3.1.2 及更高版本
Apache Spark 3 及更高版本
ClickHouse
Cloudera Impala 3.1 及更高版本
搭配原生驱动程序的 Cloudera Impala 3.1 及更高版本
使用原生驱动程序的 Cloudera Impala
DataVirtuality
Databricks
Denodo 7
Denodo 8
Dremio
Dremio 11+
Exasol
Firebolt
Google BigQuery 旧版 SQL
Google BigQuery 标准 SQL
Google Cloud PostgreSQL
Google Cloud SQL
Google Spanner
Greenplum
HyperSQL
IBM Netezza
MariaDB
Microsoft Azure PostgreSQL
Microsoft Azure SQL Database
Microsoft Azure Synapse Analytics
Microsoft SQL Server 2008 及更高版本
Microsoft SQL Server 2012 及更高版本
Microsoft SQL Server 2016
Microsoft SQL Server 2017 及更高版本
MongoBI
MySQL
MySQL 8.0.12 及更高版本
Oracle
Oracle ADWC
PostgreSQL 9.5 及更高版本
9.5 之前的 PostgreSQL
PrestoDB
PrestoSQL
SAP HANA 2+
SingleStore
SingleStore 7+
Snowflake
TeraData
Trino
向量
Vertica

若要支持持久性原生派生表(具有基于 LookML 的查询),方言还必须支持 CREATE TABLE DDL 函数。以下是最新版 Looker 中支持永久性原生(基于 LookML)派生表的方言列表:

方言 是否支持?
Actian Avalanche
Amazon Athena
Amazon Aurora MySQL
Amazon Redshift
Apache Druid
Apache Druid 0.13+
Apache Druid 0.18 及更高版本
Apache Hive 2.3 及更高版本
Apache Hive 3.1.2 及更高版本
Apache Spark 3 及更高版本
ClickHouse
Cloudera Impala 3.1 及更高版本
搭配原生驱动程序的 Cloudera Impala 3.1 及更高版本
使用原生驱动程序的 Cloudera Impala
DataVirtuality
Databricks
Denodo 7
Denodo 8
Dremio
Dremio 11+
Exasol
Firebolt
Google BigQuery 旧版 SQL
Google BigQuery 标准 SQL
Google Cloud PostgreSQL
Google Cloud SQL
Google Spanner
Greenplum
HyperSQL
IBM Netezza
MariaDB
Microsoft Azure PostgreSQL
Microsoft Azure SQL Database
Microsoft Azure Synapse Analytics
Microsoft SQL Server 2008 及更高版本
Microsoft SQL Server 2012 及更高版本
Microsoft SQL Server 2016
Microsoft SQL Server 2017 及更高版本
MongoBI
MySQL
MySQL 8.0.12 及更高版本
Oracle
Oracle ADWC
PostgreSQL 9.5 及更高版本
9.5 之前的 PostgreSQL
PrestoDB
PrestoSQL
SAP HANA 2+
SingleStore
SingleStore 7+
Snowflake
TeraData
Trino
向量
Vertica

增量构建 PDT

增量 PDT 是指 Looker 通过将新数据附加到表中(而不是重新构建整个表)构建的永久性派生表 (PDT)

如果您的方言支持增量 PDT,并且您的 PDT 使用基于触发器的持久化策略(datagroup_triggersql_trigger_valueinterval_trigger),您可以将 PDT 定义为增量 PDT

如需了解详情,请参阅增量 PDT 文档页面。

增量 PDT 支持的数据库方言

为了让 Looker 支持 Looker 项目中的增量 PDT,您的数据库方言也必须支持增量 PDT。下表显示了最新版 Looker 中支持增量 PDT 的方言:

方言 是否支持?
Actian Avalanche
Amazon Athena
Amazon Aurora MySQL
Amazon Redshift
Apache Druid
Apache Druid 0.13+
Apache Druid 0.18 及更高版本
Apache Hive 2.3 及更高版本
Apache Hive 3.1.2 及更高版本
Apache Spark 3 及更高版本
ClickHouse
Cloudera Impala 3.1 及更高版本
搭配原生驱动程序的 Cloudera Impala 3.1 及更高版本
使用原生驱动程序的 Cloudera Impala
DataVirtuality
Databricks
Denodo 7
Denodo 8
Dremio
Dremio 11+
Exasol
Firebolt
Google BigQuery 旧版 SQL
Google BigQuery 标准 SQL
Google Cloud PostgreSQL
Google Cloud SQL
Google Spanner
Greenplum
HyperSQL
IBM Netezza
MariaDB
Microsoft Azure PostgreSQL
Microsoft Azure SQL Database
Microsoft Azure Synapse Analytics
Microsoft SQL Server 2008 及更高版本
Microsoft SQL Server 2012 及更高版本
Microsoft SQL Server 2016
Microsoft SQL Server 2017 及更高版本
MongoBI
MySQL
MySQL 8.0.12 及更高版本
Oracle
Oracle ADWC
PostgreSQL 9.5 及更高版本
9.5 之前的 PostgreSQL
PrestoDB
PrestoSQL
SAP HANA 2+
SingleStore
SingleStore 7+
Snowflake
TeraData
Trino
向量
Vertica

创建 PDT

如需将派生表转换为永久性派生表 (PDT),您需要为该表定义持久化策略。为了优化效果,您还应添加优化策略

持久化策略

派生表的持久性可由 Looker 管理,对于支持具体化视图的方言,则由数据库使用具体化视图管理。

如需使派生表持久化,请将以下参数之一添加到 derived_table 定义中:

使用基于触发器的持久性策略(datagroup_triggersql_trigger_valueinterval_trigger)时,Looker 会在 PDT 触发重建之前在数据库中维护 PDT。触发 PDT 后,Looker 会重新构建 PDT 以替换之前的版本。也就是说,使用基于触发器的 PDT 时,用户无需等待 PDT 构建完毕,即可从 PDT 获取对探索查询的回答。

datagroup_trigger

数据集群是创建持久性最灵活的方法。如果您使用 sql_triggerinterval_trigger 定义了数据集,则可以使用 datagroup_trigger 参数启动永久派生表 (PDT) 的重建。

Looker 会在数据集群触发之前在数据库中维护 PDT。触发数据集群后,Looker 会重新构建 PDT 以替换之前的版本。这意味着,在大多数情况下,您的用户无需等待 PDT 的构建。如果用户在 PDT 构建期间请求数据,并且查询结果不在缓存中,Looker 将返回现有 PDT 中的数据,直到新 PDT 构建完毕。如需简要了解数据集群,请参阅缓存查询

如需详细了解再生器如何构建 PDT,请参阅Looker 再生器部分。

sql_trigger_value

sql_trigger_value 参数会根据您提供的 SQL 语句触发永久性派生表 (PDT) 的重新生成。如果 SQL 语句的结果与上一个值不同,系统会重新生成 PDT。否则,系统会在数据库中维护现有的 PDT。这意味着,在大多数情况下,您的用户无需等待 PDT 的构建。如果用户在 PDT 构建期间请求数据,并且查询结果不在缓存中,Looker 将返回现有 PDT 中的数据,直到新 PDT 构建完毕。

如需详细了解再生器如何构建 PDT,请参阅Looker 再生器部分。

interval_trigger

interval_trigger 参数会根据您提供的时间间隔(例如 "24 hours""60 minutes")触发永久性派生表 (PDT) 的重新生成。与 sql_trigger 参数类似,这意味着通常在用户查询 PDT 时,系统会预先构建 PDT。如果用户在 PDT 构建期间请求数据,并且查询结果不在缓存中,Looker 将返回现有 PDT 中的数据,直到新 PDT 构建完毕。

persist_for

另一种方法是使用 persist_for 参数设置派生表在被标记为过期之前应存储的时长,以便其不再用于查询,并从数据库中删除。

当用户首次对其运行查询时,系统会构建 persist_for 永久派生表 (PDT)。然后,Looker 会在 PDT 的 persist_for 参数中指定的时间段内在数据库中维护 PDT。如果用户在 persist_for 时间范围内查询 PDT,Looker 会尽可能使用缓存的结果,否则会在 PDT 上运行查询。

persist_for 时间过后,Looker 会从数据库中清除 PDT,并在用户下次查询 PDT 时重新构建 PDT,这意味着该查询需要等待重新构建。

使用 persist_for 的 PDT 不会由 Looker 的再生器自动重建,但在 PDT 的依赖项级联的情况下除外。如果 persist_for 表属于包含基于触发器的 PDT(使用 datagroup_triggerinterval_triggersql_trigger_value 持久化策略的 PDT)的依赖项级联,则重新生成器将监控和重新构建 persist_for 表,以便重新构建级联中的其他表。请参阅本页中的Looker 如何构建级联派生表部分。

materialized_view: yes

借助具体化视图,您可以利用数据库的功能在 Looker 项目中保留派生表。如果您的数据库方言支持具体化视图,并且您的 Looker 连接配置为启用 Enable PDTs 切换开关,则可以通过为派生表指定 materialized_view: yes 来创建具体化视图。原生派生表基于 SQL 的派生表均支持具体化视图。

永久性派生表 (PDT) 类似,具体化视图是一种查询结果,会以表的形式存储在数据库的临时架构中。PDT 与具体化视图之间的主要区别在于表的刷新方式:

  • 对于 PDT,持久性策略在 Looker 中定义,持久性由 Looker 管理。
  • 对于具体化视图,数据库负责维护和刷新表中的数据。

因此,若要使用具体化视图功能,您需要对方言及其特性有深入的了解。在大多数情况下,每当数据库在具体化视图查询的表中检测到新数据时,都会刷新具体化视图。具体化视图非常适合需要实时数据的场景。

如需了解方言支持、要求和重要注意事项,请参阅 materialized_view 参数文档页面。

优化策略

由于永久派生表 (PDT) 存储在数据库中,因此您应根据方言的支持情况,使用以下策略优化 PDT:

例如,如需向派生表示例添加持久性,您可以将其设置为在数据集群 orders_datagroup 触发时重新构建,并在 customer_idfirst_order 上添加索引,如下所示:

view: customer_order_summary {
  derived_table: {
    explore_source: orders {
      ...
    }
    datagroup_trigger: orders_datagroup
    indexes: ["customer_id", "first_order"]
  }
}

如果您未添加索引(或相应方言的等效项),Looker 会警告您应添加索引以提高查询性能。

PDT 的使用场景

永久性派生表 (PDT) 非常有用,因为它们可以将查询结果保留在表中,从而提高查询性能。

一般而言,最佳实践是,除非绝对必要,否则开发者应尝试在不使用 PDT 的情况下对数据进行建模。

在某些情况下,可以通过其他方式优化数据。例如,添加索引或更改列的数据类型可能会解决问题,而无需创建 PDT。请务必使用 SQL Runner 工具中的“说明”功能分析运行缓慢的查询的执行计划。

除了缩短经常运行的查询的查询时间和数据库负载之外,PDT 还有其他一些用例,包括:

如果没有合理的方法将表中的唯一行标识为主键,您还可以使用 PDT 定义主键

使用 PDT 测试优化

您可以使用 PDT 测试不同的索引、分布和其他优化选项,而无需获得 DBA 或 ETL 开发者的大量支持。

假设您有一个表,但想测试不同的索引。该视图的初始 LookML 可能如下所示:

view: customer {
  sql_table_name: warehouse.customer ;;
}

如需测试优化策略,您可以使用 indexes 参数向 LookML 添加索引,如下所示:

view: customer {
  # sql_table_name: warehouse.customer
  derived_table: {
    sql: SELECT * FROM warehouse.customer ;;
    persist_for: "8 hours"
    indexes: [customer_id, customer_name, salesperson_id]
  }
}

查询视图一次以生成 PDT。然后,运行测试查询并比较结果。如果结果理想,您可以要求 DBA 或 ETL 团队向原始表添加索引。

请务必将视图代码改回来,以移除 PDT。

使用 PDT 预联接或汇总数据

预先联接或预先汇总数据有助于针对大量或多种类型的数据调整查询优化。

例如,假设您想要根据客户首次下单的时间,按同类群组创建客户查询。如果每次需要实时数据时都运行此查询,可能会很昂贵;不过,您只需计算一次查询,然后使用 PDT 重复使用结果:

view: customer_order_facts {
  derived_table: {
    sql: SELECT
    c.customer_id,
    MIN(o.order_date) OVER (PARTITION BY c.customer_id) AS first_order_date,
    MAX(o.order_date) OVER (PARTITION BY c.customer_id) AS most_recent_order_date,
    COUNT(o.order_id) OVER (PARTITION BY c.customer_id) AS lifetime_orders,
    SUM(o.order_value) OVER (PARTITION BY c.customer_id) AS lifetime_value,
    RANK() OVER (PARTITION BY c.customer_id ORDER BY o.order_date ASC) AS order_sequence,
    o.order_id
    FROM warehouse.customer c LEFT JOIN warehouse.order o ON c.customer_id = o.customer_id
    ;;
    sql_trigger_value: SELECT CURRENT_DATE ;;
    indexes: [customer_id, order_id, order_sequence, first_order_date]
  }
}

级联派生表

您可以在一个派生表的定义中引用另一个派生表,从而创建一个级联派生表级联永久性派生表 (PDT) 链。级联派生表的示例如下:表 TABLE_D 依赖于另一个表 TABLE_C,而 TABLE_C 依赖于 TABLE_BTABLE_B 依赖于 TABLE_A

引用派生表的语法

如需在另一个派生表中引用派生表,请使用以下语法:

`${derived_table_or_view_name.SQL_TABLE_NAME}`

在此格式中,SQL_TABLE_NAME 是字面量字符串。例如,您可以使用以下语法引用 clean_events 派生表:

`${clean_events.SQL_TABLE_NAME}`

您可以使用相同的语法来引用 LookML 视图。同样,在本例中,SQL_TABLE_NAME 是字面量字符串。

在下一个示例中,系统会根据数据库中的 events 表创建 clean_events PDT。clean_events PDT 会从 events 数据库表中滤除不需要的行。然后,系统会显示第二个 PDT;event_summary PDT 是 clean_events PDT 的摘要。每当向 clean_events 添加新行时,event_summary 表都会重新生成。

event_summary PDT 和 clean_events PDT 是级联 PDT,其中 event_summary 依赖于 clean_events(因为 event_summary 是使用 clean_events PDT 定义的)。此特定示例可以在单个 PDT 中更高效地完成,但对于演示派生表引用非常有用。

view: clean_events {
  derived_table: {
    sql:
      SELECT *
      FROM events
      WHERE type NOT IN ('test', 'staff') ;;
    datagroup_trigger: events_datagroup
  }
}

view: events_summary {
  derived_table: {
    sql:
      SELECT
        type,
        date,
        COUNT(*) AS num_events
      FROM
        ${clean_events.SQL_TABLE_NAME} AS clean_events
      GROUP BY
        type,
        date ;;
    datagroup_trigger: events_datagroup
  }
}

虽然这并不总是必需的,但当您以这种方式引用派生表时,通常很有用的是使用以下格式为表创建别名:

${derived_table_or_view_name.SQL_TABLE_NAME} AS derived_table_or_view_name

前面的示例会执行以下操作:

${clean_events.SQL_TABLE_NAME} AS clean_events

使用别名很有帮助,因为在后台,PDT 在数据库中使用长代码进行命名。在某些情况下(尤其是在使用 ON 子句时),很容易忘记需要使用 ${derived_table_or_view_name.SQL_TABLE_NAME} 语法来检索这个长名称。别名有助于避免此类错误。

Looker 如何构建级联派生表

如果是级联的临时派生表,如果用户的查询结果不在缓存中,Looker 将构建查询所需的所有派生表。如果您有一个 TABLE_D,其定义包含对 TABLE_C 的引用,则 TABLE_D 依赖TABLE_C。这意味着,如果您查询 TABLE_D,而该查询不在 Looker 的缓存中,Looker 将重新构建 TABLE_D。但首先,它必须重建 TABLE_C

现在,我们来看一个级联临时派生表场景,其中 TABLE_D 依赖于 TABLE_CTABLE_C 依赖于 TABLE_BTABLE_B 依赖于 TABLE_A。如果 Looker 在缓存中没有针对 TABLE_C 的有效查询结果,则会构建查询所需的所有表。因此,Looker 将先构建 TABLE_A,然后构建 TABLE_B,最后构建 TABLE_C

在这种情况下,TABLE_A 必须先完成生成,然后 Looker 才能开始生成 TABLE_B,以此类推,直到 TABLE_C 完成生成,Looker 才能提供查询结果。(由于无需 TABLE_D 即可回答此查询,因此 Looker 目前不会重新构建 TABLE_D。)

如需查看使用相同数据群组的级联 PDT 的示例场景,请参阅 datagroup 参数文档页面。

同样的基本逻辑也适用于 PDT:Looker 会沿着依赖项链构建回答查询所需的所有表。但对于 PDT,表通常已经存在,不需要重新构建。对于对级联 PDT 的标准用户查询,只有当数据库中没有有效的 PDT 版本时,Looker 才会重新构建级联中的 PDT。如果您想强制重新构建级联中的所有 PDT,可以通过“探索”手动重新构建查询的表

请务必了解一个重要的逻辑要点:在 PDT 级联的情况下,依赖的 PDT 本质上是在查询其依赖的 PDT。这对于使用 persist_for 策略的 PDT 尤为重要。通常,系统会在用户查询 persist_for PDT 时构建这些 PDT,它们会一直保留在数据库中,直到其 persist_for 间隔结束,然后在用户下次查询时才会重新构建。不过,如果 persist_for PDT 是基于触发器的 PDT(使用 datagroup_triggerinterval_triggersql_trigger_value 持久化策略的 PDT)的级联的一部分,则每当其依赖的 PDT 被重新构建时,系统都会查询 persist_for PDT。因此,在本例中,persist_for PDT 将按照其依赖 PDT 的时间安排进行重新构建。这意味着,persist_for PDT 可能会受到其依赖项的持久化策略的影响。

手动为查询重新构建持久表

用户可以在“探索”的菜单中选择重新构建派生表并运行选项,以替换持久性设置,并重新构建“探索”中当前查询所需的所有永久性派生表 (PDT) 和汇总表

点击“探索操作”按钮可打开“探索”菜单,从中选择“重新构建派生表并运行”。

只有拥有 develop 权限的用户才能看到此选项,而且只有在“探索”查询加载后才能看到。

重新构建派生表并运行选项会重新构建回答查询所需的所有永久表(所有 PDT 和汇总表),无论其持久性策略如何。这包括当前查询中的所有汇总表和 PDT,还包括当前查询中的汇总表和 PDT 引用的所有汇总表和 PDT。

对于增量 PDT重新构建派生表并运行选项会触发新增量的构建。对于增量 PDT,增量包括 increment_key 参数中指定的时间段,以及 increment_offset 参数中指定的上一个时间段的数量(如果有)。请参阅增量 PDT 文档页面,查看一些示例场景,了解增量 PDT 是如何根据其配置进行构建的。

对于级联 PDT,这意味着从顶部开始重新构建级联中的所有派生表。这与在临时派生表级联中查询表时的行为相同:

如果 table_c 依赖于 table_b,而 table_b 依赖于 table_a,那么重新构建 table_c 时,系统会先重新构建 table_a,然后再重新构建 table_b,最后再重新构建 table_c。

请注意有关手动重新构建派生表的以下事项:

  • 对于发起重新构建派生表并运行操作的用户,查询将等待表重新构建完毕,然后再加载结果。其他用户的查询仍会使用现有表。重新构建永久性表后,所有用户都将使用重新构建的表。虽然此过程旨在避免在重新构建表时中断其他用户的查询,但这些用户可能仍会受到数据库上额外负载的影响。如果您遇到以下情况,即在工作时间触发重新构建可能会给数据库带来不可接受的压力,则可能需要告知用户,他们绝不应在这些时间重新构建特定的 PDT 或汇总表。
  • 如果用户处于开发模式,并且探索基于开发表,则重新构建派生表并运行操作将为探索重新构建开发表,而不是生产表。但是,如果开发模式下的“探索”使用的是派生表的正式版,则系统会重新构建正式版表。如需了解开发表和生产表,请参阅开发模式下的永久性表

  • 对于由 Looker 托管的实例,如果派生表的重建时间超过一小时,则表将无法成功重建,并且浏览器会话将超时。如需详细了解可能会影响 Looker 进程的超时问题,请参阅管理设置 - 查询文档页面中的查询超时和队列部分。

开发模式下的永久表

Looker 在开发模式下管理持久表时会有一些特殊行为。

如果您在开发模式下查询某个持久表,未对其定义进行任何更改,Looker 将查询该表的正式版。如果您确实更改了表定义,而更改会影响表中的数据或表的查询方式,则系统会在您下次在开发模式下查询表时创建表的新开发版本。有了这样的开发表,您就可以在不干扰最终用户的情况下测试更改。

促使 Looker 创建开发表的原因

无论您是在开发模式下还是生产模式下,Looker 都会尽可能使用现有的生产表来回答查询。但在某些情况下,Looker 无法在开发模式下使用生产表进行查询:

  • 如果您的永久性表具有用于缩小其数据集的参数,以便在开发模式下更快地运行
  • 如果您更改了永久性表的定义,而更改会影响表中的数据

如果您处于开发模式,并且查询使用带有 if prodif dev 语句的条件 WHERE 子句定义的基于 SQL 的派生表,Looker 将构建开发表。

对于在开发模式下没有用于缩小数据集范围的参数的永久表,Looker 会使用表的生产版本来回答开发模式下的查询,除非您更改表的定义,然后在开发模式下查询表。这适用于对表进行的任何更改,只要这些更改会影响表中的数据或表的查询方式。

以下是一些会促使 Looker 创建永久表的开发版本的更改类型示例(只有在您在进行这些更改后随后查询该表时,Looker 才会创建该表):

对于不会修改表中数据或影响 Looker 查询表的方式的更改,Looker 不会创建开发表。publish_as_db_view 参数就是一个很好的例子:在开发模式下,如果您仅更改派生表的 publish_as_db_view 设置,Looker 无需重新构建派生表,因此不会创建开发表。

Looker 会将开发表保留多长时间

无论表的实际持久化策略如何,Looker 都会将开发持久化表视为采用 persist_for: "24 hours" 持久化策略。Looker 之所以这样做,是为了确保开发表不会保留超过一天,因为 Looker 开发者可能会在开发过程中查询表的多次迭代,并且每次构建新开发表时都会这样做。为防止开发表占用数据库空间,Looker 会应用 persist_for: "24 hours" 策略,确保定期从数据库中清理表。

否则,Looker 在开发模式下构建永久性派生表 (PDT) 和汇总表的方式与在生产模式下构建永久表的方式相同。

如果您在将更改部署到 PDT 或汇总表时,开发表会保留在数据库中,Looker 通常会将开发表用作生产表,这样用户在查询表时就不必等待表构建。

请注意,在部署更改后,您可能仍需要重新构建表才能在生产环境中对其进行查询,具体取决于具体情况:

  • 如果您在开发模式下查询表的时间已超过 24 小时,则该表的开发版本会被标记为已过期,并且不会用于查询。您可以使用 Looker IDE“永久派生表”页面的开发标签页检查未构建的 PDT。如果您有未构建的 PDT,可以在进行更改之前直接在开发模式下对其进行查询,以便开发表可在生产环境中使用。
  • 如果持久化表包含 dev_filters 参数(对于原生派生表)或使用 if prodif dev 语句的条件 WHERE 子句(对于基于 SQL 的派生表),则开发表无法用作生产版本,因为开发版本的数据集较短。如果是这种情况,在开发完表格后,在部署更改之前,您可以注释掉 dev_filters 参数或条件 WHERE 子句,然后在开发模式下查询表格。然后,Looker 会构建表的完整版本,以便您在部署更改时将其用于生产环境。

否则,如果您在没有可用作生产表的有效开发表时部署更改,Looker 将在下次以生产模式查询表时(对于使用 persist_for 策略的持久表)或下次运行再生器时(对于使用 datagroup_triggerinterval_triggersql_trigger_value 的持久表)重新构建表。

在开发模式下检查是否有未构建的 PDT

如果您在将更改部署到永久派生表 (PDT) 或汇总表时,开发表会保留在数据库中,Looker 通常会将开发表用作生产表,这样用户在查询表时就不必等待表构建。如需了解详情,请参阅本页中的Looker 会将开发表保留多长时间是什么原因促使 Looker 创建开发表部分。

因此,最好在部署到生产环境时构建所有 PDT,以便表格可以立即用作生产版本。

您可以在项目健康状况面板中检查项目是否存在未构建的 PDT。点击 Looker IDE 中的 Project Health 图标,打开 Project Health 面板。然后点击 Validate PDT Status(验证 PDT 状态)按钮。

如果有未构建的 PDT,Project Health 面板会将其列出:

“项目健康状况”面板会显示项目的未构建 PDT 列表,以及“转到 PDT 管理”按钮。

如果您拥有 see_pdts 权限,可以点击前往 PDT 管理按钮。Looker 将打开永久性派生表页面的开发标签页,并将结果过滤到您的特定 LookML 项目。在该页面中,您可以查看哪些开发 PDT 已构建和未构建,以及访问其他问题排查信息。如需了解详情,请参阅管理设置 - 永久派生表文档页面。

在项目中找到未构建的 PDT 后,您可以打开用于查询表的“探索”,然后使用“探索”菜单中的重新构建派生表并运行选项来构建开发版本。请参阅本页面上的手动重新构建查询的永久表部分。

表共享和清理

在任何给定的 Looker 实例中,如果表具有相同的定义和相同的持久化方法设置,Looker 会在用户之间共享这些持久化表。此外,如果表的定义不复存在,Looker 会将该表标记为已过期。

这样做有几个好处:

  • 如果您在开发模式下未对表进行任何更改,则您的查询将使用现有的生产表。除非您的表是基于 SQL 的派生表(使用带有 if prodif dev 语句的条件 WHERE 子句定义),否则就会出现这种情况。如果表是使用条件 WHERE 子句定义的,那么当您在开发模式下查询该表时,Looker 会构建一个开发表。(对于包含 dev_filters 参数的原生派生表,Looker 具有使用生产表在开发模式下回答查询的逻辑,除非您更改表的定义,然后在开发模式下查询表。)
  • 如果两位开发者在开发模式下对某个表进行了相同的更改,则他们将共用同一开发表。
  • 将更改从开发模式推送到生产模式后,旧的生产定义将不复存在,因此旧的生产表会被标记为已过期并被删除。
  • 如果您决定舍弃开发模式更改,则该表定义将不复存在,因此不需要的开发表会被标记为已过期并被删除。

在开发模式下更快地工作

在某些情况下,您创建的永久派生表 (PDT) 需要很长时间才能生成,如果您在开发模式下测试大量更改,这可能会非常耗时。对于这些情况,您可以在开发模式下提示 Looker 创建较小版本的派生表。

对于原生派生表,您可以使用 explore_sourcedev_filters 子参数指定仅应用于派生表的开发版本的过滤条件:

view: e_faa_pdt {
  derived_table: {
  ...
    datagroup_trigger: e_faa_shared_datagroup
    explore_source: flights {
      dev_filters: [flights.event_date: "90 days"]
      filters: [flights.event_date: "2 years", flights.airport_name: "Yucca Valley Airport"]
      column: id {}
      column: airport_name {}
      column: event_date {}
    }
  }
...
}

此示例包含一个 dev_filters 参数,用于过滤过去 90 天内的数据;还包含一个 filters 参数,用于过滤过去 2 年内的数据,并将过滤条件限定为尤卡谷机场。

dev_filters 参数与 filters 参数搭配使用,以便将所有过滤条件应用于表的开发版本。如果 dev_filtersfilters 都为同一列指定了过滤条件,则对于表的开发版本,dev_filters 优先于 filters。在此示例中,开发版表格将过滤出过去 90 天内与尤卡谷机场相关的数据。

对于基于 SQL 的派生表,Looker 支持条件 WHERE 子句,并针对表的正式版 (if prod) 和开发版 (if dev) 提供了不同的选项:

view: my_view {
  derived_table: {
    sql:
      SELECT
        columns
      FROM
        my_table
      WHERE
        -- if prod -- date > '2000-01-01'
        -- if dev -- date > '2020-01-01'
      ;;
  }
}

在此示例中,当处于“生产”模式时,查询将包含 2000 年之后的所有数据,但当处于“开发”模式时,查询将仅包含 2020 年之后的数据。通过战略性地使用此功能来限制结果集并提高查询速度,可以更轻松地验证开发模式更改。

Looker 如何构建 PDT

在持久派生表 (PDT) 被定义并首次运行或由再生器触发以根据其持久化策略进行重新构建后,Looker 将执行以下步骤:

  1. 使用派生表 SQL 构建 CREATE TABLE AS SELECT(或 CTAS)语句并执行它。例如,如需重新构建名为 customer_orders_facts 的 PDT,请执行以下命令:CREATE TABLE tmp.customer_orders_facts AS SELECT ... FROM ... WHERE ...
  2. 在构建表时发出语句以创建索引
  3. 将表从 LC$..(“Looker Create”)重命名为 LR$..(“Looker Read”),以指示表已可供使用
  4. 删除不再使用的任何旧版表

这有几个重要的影响:

  • 用于构成派生表的 SQL 语句必须在 CTAS 语句中有效。
  • SELECT 语句的结果集中的列别名必须是有效的列名称。
  • 指定分布、排序键和索引时使用的名称必须是派生表的 SQL 定义中列出的列名称,而不是在 LookML 中定义的字段名称。

Looker 重新生成器

Looker 重新生成器会检查状态,并为触发器持久化表启动重建。触发器持久性表是指使用触发器作为持久性策略的永久性派生表 (PDT) 或汇总表

  • 对于使用 sql_trigger_value 的表,触发器是表的 sql_trigger_value 参数中指定的查询。当最新的触发器查询检查结果与上一个触发器查询检查结果不同时,Looker 重建器会触发表的重建。例如,如果派生表是使用 SQL 查询 SELECT CURDATE() 持久化的,那么在日期发生变化后,Looker 重建程序在下次检查触发器时会重新构建该表。
  • 对于使用 interval_trigger 的表,触发器是表的 interval_trigger 参数中指定的时间时长。Looker 重新生成器会在指定时间过后触发表的重建。
  • 对于使用 datagroup_trigger 的表,触发器可以是关联数据集的 sql_trigger 参数中指定的查询,也可以是数据集的 interval_trigger 参数中指定的时间时长。

Looker 再生器还会为使用 persist_for 参数的持久化表启动重建,但前提是 persist_for 表是触发器持久化表的依赖项级联。在这种情况下,Looker 重建程序将为 persist_for 表启动重建,因为该表需要重建级联中的其他表。否则,再生器不会监控使用 persist_for 策略的持久表。

Looker 重新生成器周期会在 Looker 管理员在数据库连接的“数据集和 PDT 维护时间表”设置中配置的定期间隔时间(默认间隔时间为 5 分钟)开始。不过,Looker 再生器会等到完成上一个周期的所有检查和 PDT 重新构建后,才会开始新的周期。这意味着,如果您有长时间运行的 PDT build,Looker 重建周期的运行频率可能不如数据组和 PDT 维护时间表设置中所定义的频率。其他因素可能会影响重新构建表所需的时间,如本页的实现持久表的重要注意事项部分所述。

如果 PDT 构建失败,再生器可能会尝试在下一个再生器周期内重新构建表:

  • 如果数据库连接上启用了重试失败的 PDT 构建设置,Looker 重新生成器将尝试在下一个重新生成器周期内重新构建表,即使表未满足触发条件也是如此。
  • 如果停用了重试失败的 PDT 构建设置,则在满足 PDT 的触发条件之前,Looker 重建程序不会尝试重新构建表。

如果用户在持久化表正在构建时请求该表中的数据,并且查询结果不在缓存中,Looker 会检查现有表是否仍然有效。(如果旧表与新版表不兼容,则可能无效。如果新表的定义不同、使用不同的数据库连接或使用其他版本的 Looker 创建,就可能会出现这种情况。)如果现有表仍然有效,Looker 将返回现有表中的数据,直到新表构建完毕。否则,如果现有表无效,Looker 会在重新构建新表后提供查询结果。

实现持久表的重要注意事项

考虑到永久性表(PDT 和汇总表)的实用性,您很容易在 Looker 实例中累积许多此类表。您可以创建一个场景,其中 Looker 重新生成器需要同时构建多个表。尤其是对于级联表或长时间运行的表,您可以创建表在重建之前需要等待很长时间的场景,或者在数据库努力生成表时,用户在从表中获取查询结果时会遇到延迟的情况。

Looker 的重新生成器会检查 PDT 触发器,以确定是否应重新构建触发器持久化表。重新生成器周期的设置间隔由 Looker 管理员在数据库连接的数据组和 PDT 维护时间表设置中配置(默认间隔为 5 分钟)。

以下几个因素可能会影响重建表所需的时间:

  • Looker 管理员可能已通过数据库连接的 Datagroup and PDT Maintenance Schedule 设置更改了再生器触发器检查的间隔时间。
  • Looker 再生器会等到完成上一个周期的所有检查和 PDT 重新构建后,才会开始新的周期。因此,如果您有长时间运行的 PDT build,Looker 再生器周期可能不会像数据组和 PDT 维护时间表设置那样频繁。
  • 默认情况下,重新生成器一次只能通过一个连接重新构建一个 PDT 或汇总表。Looker 管理员可以使用连接设置中的 PDT 构建器连接数上限字段来调整重新生成器允许的并发重建数量。
  • 由同一 datagroup 触发的所有 PDT 和汇总表都会在同一重生成过程中重建。如果有许多表直接或因级联依赖项而使用该数据集,这可能会造成较大的负载。

除了上述注意事项外,在某些情况下,您还应避免向派生表添加持久性:

  • 派生表何时会扩展 - PDT 的每次扩展都会在数据库中创建表的新副本。
  • 派生表使用模板化过滤条件或 Liquid 参数时 - 不支持使用模板化过滤条件或 Liquid 参数的派生表。
  • 原生派生表是通过使用用户属性access_filterssql_always_where 的探索构建的,系统会在数据库中为指定的每个可能的用户属性值构建表的副本。
  • 当基础数据频繁更改且您的数据库方言不支持增量 PDT 时。
  • 创建 PDT 所需的费用和时间过高。

根据 Looker 连接中持久化表的数量和复杂性,队列中可能包含需要在每个周期检查和重新构建的许多持久化表,因此在 Looker 实例上实现派生表时,请务必注意这些因素。

通过 API 批量管理 PDT

随着您在实例中创建越来越多的 PDT,监控和管理按不同时间表刷新的永久性派生表 (PDT) 会变得越来越复杂。不妨考虑使用 Looker 的 Apache Airflow 集成,将 PDT 时间表与其他 ETL 和 ELT 流程一起管理。

监控和排查 PDT 问题

如果您使用永久性派生表 (PDT),尤其是级联 PDT,查看 PDT 的状态会很有帮助。您可以使用 Looker 的永久性派生表管理页面查看 PDT 的状态。如需了解详情,请参阅管理设置 - 永久派生表文档页面。

尝试排查 PDT 问题时,请注意以下事项:

  • 在调查 PDT 事件日志时,请特别注意开发表和生产表之间的区别。
  • 验证 Looker 存储永久派生表的临时架构是否未发生任何更改。如果已进行更改,您可能需要更新 Looker 的管理部分中的连接设置,然后可能需要重启 Looker 才能恢复正常的 PDT 功能。
  • 确定是所有 PDT 都存在问题,还是只有一个 PDT 存在问题。如果其中一个出现问题,则问题可能由 LookML 或 SQL 错误引起。
  • 确定 PDT 存在的问题是否与其安排的重新构建时间有关。
  • 确保所有 sql_trigger_value 查询均能成功求值,并且仅返回一行和一列。对于基于 SQL 的 PDT,您可以在 SQL Runner 中运行它们来实现此目的。(应用 LIMIT 可防止查询无限期运行。)如需详细了解如何使用 SQL Runner 调试派生表,请参阅使用 SQL Runner 测试派生表 社区帖子。
  • 对于基于 SQL 的 PDT,请使用 SQL Runner 验证 PDT 的 SQL 是否能无错误地执行。(请务必在 SQL Runner 中应用 LIMIT,以确保查询时间合理。)
  • 对于基于 SQL 的派生表,请避免使用通用表表达式 (CTE)。将 CTE 与 DT 搭配使用会创建嵌套的 WITH 语句,这可能会导致 PDT 失败且不显示警告。请改为使用 CTE 的 SQL 创建次级 DT,然后使用 ${derived_table_or_view_name.SQL_TABLE_NAME} 语法从第一个 DT 引用该 DT。
  • 检查问题 PDT 依赖的所有表(无论是普通表还是 PDT 本身)是否存在且可查询。
  • 确保问题 PDT 依赖的所有表都没有任何共享或独占锁。为了成功构建 PDT,Looker 需要对要更新的表获取独占锁。这将与表上当前的其他共享锁或独占锁冲突。在所有其他锁都解除之前,Looker 将无法更新 PDT。同样,对于 Looker 要根据其构建 PDT 的表上的任何独占锁,也是如此;如果表上存在独占锁,则在独占锁清除之前,Looker 将无法获取共享锁来运行查询。
  • 使用 SQL Runner 中的显示进程按钮。如果有大量进程处于活跃状态,则可能会导致查询时间变慢。
  • 监控查询中的注释。请参阅本页中的查询 PDT 的评论部分。

查询 PDT 的评论

数据库管理员可以轻松区分常规查询与生成永久派生表 (PDT) 的查询。Looker 会向 CREATE TABLE ... AS SELECT ... 语句添加注释,其中包含 PDT 的 LookML 模型和视图,以及 Looker 实例的唯一标识符 (slug)。如果是在开发者模式下代表用户生成 PDT,则注释中会显示用户的 ID。PDT 生成的注释遵循以下模式:

-- Building `<view_name>` in dev mode for user `<user_id>` on instance `<instance_slug>`
CREATE TABLE `<table_name>` SELECT ...
-- finished `<view_name>` => `<table_name>`

如果 Looker 必须为探索的查询生成 PDT,则“PDT 生成”注释将显示在“探索”的“SQL”标签页中。该注释将显示在 SQL 语句的顶部。

最后,在查询管理页面上,对于每个查询,查询详情弹出式窗口信息标签页中的消息字段中都会显示 PDT 生成注释。

在失败后重新构建 PDT

当永久性派生表 (PDT) 发生失败时,查询该 PDT 时会发生以下情况:

  • 如果之前运行过相同的查询,Looker 将使用缓存中的结果。(如需了解其运作方式,请参阅缓存查询文档页面。)
  • 如果结果不在缓存中,Looker 会从数据库中的 PDT 中提取结果(如果存在有效的 PDT 版本)。
  • 如果数据库中没有有效的 PDT,Looker 会尝试重新构建 PDT。
  • 如果无法重新构建 PDT,Looker 会针对查询返回错误。下次查询 PDT 或 PDT 的持久化策略触发重建时,Looker 再生器会尝试重新构建 PDT。

对于级联 PDT,同样适用上述逻辑,但对于级联 PDT:

  • 如果为某个表构建失败,则会导致依赖项链中的 PDT 无法构建。
  • 依赖的 PDT 本质上会查询其依赖的 PDT,因此一个表的持久化策略可能会触发沿链向上重建 PDT。

回顾前面的级联表示例,其中 TABLE_D 依赖于 TABLE_CTABLE_C 依赖于 TABLE_BTABLE_B 依赖于 TABLE_A

如果 TABLE_B 发生失败,则所有标准(非级联)行为都适用于 TABLE_B:如果对 TABLE_B 进行查询,Looker 会先尝试使用缓存返回结果,然后尝试使用表的先前版本(如果可能),然后尝试重新构建表,最后如果 TABLE_B 无法重新构建,则会返回错误。在下次查询该表或该表的持久化策略下次触发重新构建时,Looker 会再次尝试重新构建 TABLE_B

TABLE_B 的依赖项也是如此。因此,如果无法构建 TABLE_B,并且有对 TABLE_C 的查询:

  • Looker 会尝试对 TABLE_C 上的查询使用缓存。
  • 如果结果不在缓存中,Looker 会尝试从数据库中的 TABLE_C 中提取结果。
  • 如果没有有效的 TABLE_C 版本,Looker 会尝试重新构建 TABLE_C,这会在 TABLE_B 上创建查询。
  • 然后,Looker 会尝试重新构建 TABLE_B(如果 TABLE_B 未修复,则会失败)。
  • 如果无法重新构建 TABLE_B,则无法重新构建 TABLE_C,因此 Looker 会针对 TABLE_C 上的查询返回错误。
  • 然后,Looker 会尝试根据其常规持久化策略重建 TABLE_C,或者在下次查询 PDT 时重建 TABLE_C(包括 TABLE_D 下次尝试构建时,因为 TABLE_D 依赖于 TABLE_C)。

解决 TABLE_B 的问题后,TABLE_B 和每个依赖表将尝试根据其持久化策略进行重新构建,或者在下次被查询时(包括依赖 PDT 下次尝试重新构建时)进行重新构建。或者,如果在开发模式下构建了分级中 PDT 的开发版本,则可以将开发版本用作新的生产 PDT。(如需了解其运作方式,请参阅本页上的开发模式下的永久性表部分。)或者,您也可以使用“探索”对 TABLE_D 运行查询,然后手动重新构建查询的 PDT,这将强制重新构建依赖项级联中的所有 PDT。

提高 PDT 性能

创建永久性派生表 (PDT) 时,性能可能会成为一个问题。尤其是当表非常大时,查询表的速度可能会很慢,就像数据库中的任何大型表一样。

您可以通过过滤数据控制 PDT 中数据的排序和编制索引方式来提高性能。

添加过滤条件以限制数据集

对于特别庞大的数据集,如果行数很多,则会导致对永久派生表 (PDT) 的查询速度变慢。如果您通常只查询近期数据,不妨考虑向 PDT 的 WHERE 子句添加一个过滤条件,将表格中的数据限制为 90 天或更短的时间范围。这样,每次重新构建表时,系统只会向表中添加相关数据,从而加快运行查询的速度。然后,您可以创建一个单独的较大 PDT 以进行历史分析,以便快速查询近期数据,同时也能查询旧数据。

使用 indexessortkeysdistribution

创建大型永久派生表 (PDT) 时,为表编入索引(对于 MySQL 或 Postgres 等方言)或添加排序键和分布(对于 Redshift)有助于提升性能。

通常,最好在 ID 或日期字段中添加 indexes 参数。

对于 Redshift,通常最好在 ID 或日期字段上添加 sortkeys 参数,并在用于联接的字段上添加 distribution 参数。

以下设置用于控制永久派生表 (PDT) 中数据的排序和编制索引方式。以下设置是可选设置,但强烈建议您进行设置:

  • 对于 Redshift 和 Aster,请使用 distribution 参数指定列名称,其值用于在集群中分散数据。当两个表通过 distribution 参数中指定的列联接时,数据库可以在同一节点上找到联接数据,从而最大限度地减少节点间 I/O。
  • 对于 Redshift,请将 distribution_style 参数设置为 all,以指示数据库在每个节点上保留数据的完整副本。在联接相对较小的表时,这通常用于最大限度地减少节点间 I/O。将此值设置为 even 可指示数据库在不使用分布列的情况下将数据均匀分布在集群中。只有在未指定 distribution 时才能指定此值。
  • 对于 Redshift,请使用 sortkeys 参数。这些值指定了 PDT 的哪些列用于对磁盘上的数据进行排序,以便于搜索。在 Redshift 上,您可以使用 sortkeysindexes,但不能同时使用这两者。
  • 在大多数数据库中,请使用 indexes 参数。这些值指定 PDT 的哪些列会编入索引。(在 Redshift 中,索引用于生成交错排序键。)