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

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

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

基于 SQL 的派生表

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

通常,您可以在 view 参数的 derived_table 参数内使用 sql 参数定义 SQL 查询。

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

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

  • create_process:当您将 sql 参数用于 PDT 时,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 中的派生表:

方言 是否支持?
艾克蒂安雪崩
Amazon Athena
Amazon Aurora MySQL
Amazon Redshift
阿帕奇·德鲁伊
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 11 及更高版本
Exasol
火箭
Google BigQuery 旧版 SQL
Google BigQuery 标准 SQL
Google Cloud PostgreSQL
Google Cloud SQL
Google Spanner
绿紫红
HyperSQL
IBM Netezza
MariaDB
Microsoft Azure PostgreSQL
Microsoft Azure SQL 数据库
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 及更高版本
PostgreSQL 9.5 版之前的版本
PrestoDB
PrestoSQL
SAP HANA
SAP HANA 2 及更高版本
SingleStore
SingleStore 7 或更高版本
Snowflake
Teradata
Trino
矢量
Vertica

永久性派生表

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

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

针对 PDT 的要求

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

PDT 支持的数据库方言

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

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

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

方言 是否支持?
艾克蒂安雪崩
Amazon Athena
Amazon Aurora MySQL
Amazon Redshift
阿帕奇·德鲁伊
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 11 及更高版本
Exasol
火箭
Google BigQuery 旧版 SQL
Google BigQuery 标准 SQL
Google Cloud PostgreSQL
Google Cloud SQL
Google Spanner
绿紫红
HyperSQL
IBM Netezza
MariaDB
Microsoft Azure PostgreSQL
Microsoft Azure SQL 数据库
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 及更高版本
PostgreSQL 9.5 版之前的版本
PrestoDB
PrestoSQL
SAP HANA
SAP HANA 2 及更高版本
SingleStore
SingleStore 7 或更高版本
Snowflake
Teradata
Trino
矢量
Vertica

如需支持永久性原生派生表(具有基于 LookML 的查询),此方言还必须支持 CREATE TABLE DDL 函数。下面列出了最新版 Looker 中支持永久性原生(基于 Looker)的派生表的方言列表:

方言 是否支持?
艾克蒂安雪崩
Amazon Athena
Amazon Aurora MySQL
Amazon Redshift
阿帕奇·德鲁伊
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 11 及更高版本
Exasol
火箭
Google BigQuery 旧版 SQL
Google BigQuery 标准 SQL
Google Cloud PostgreSQL
Google Cloud SQL
Google Spanner
绿紫红
HyperSQL
IBM Netezza
MariaDB
Microsoft Azure PostgreSQL
Microsoft Azure SQL 数据库
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 及更高版本
PostgreSQL 9.5 版之前的版本
PrestoDB
PrestoSQL
SAP HANA
SAP HANA 2 及更高版本
SingleStore
SingleStore 7 或更高版本
Snowflake
Teradata
Trino
矢量
Vertica

逐步构建 PDT

增量 PDT 是一种永久性派生表 (PDT),Looker 通过向该表附加新数据(而非整个表)来构建该表。

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

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

增量 PDT 支持的数据库方言

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

方言 是否支持?
艾克蒂安雪崩
Amazon Athena
Amazon Aurora MySQL
Amazon Redshift
阿帕奇·德鲁伊
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 11 及更高版本
Exasol
火箭
Google BigQuery 旧版 SQL
Google BigQuery 标准 SQL
Google Cloud PostgreSQL
Google Cloud SQL
Google Spanner
绿紫红
HyperSQL
IBM Netezza
MariaDB
Microsoft Azure PostgreSQL
Microsoft Azure SQL 数据库
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 及更高版本
PostgreSQL 9.5 版之前的版本
PrestoDB
PrestoSQL
SAP HANA
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,期限为 PDT 的 persist_for 参数中指定的时长。如果用户在 persist_for 内查询 PDT,Looker 会使用缓存的结果(如果可能),否则会在 PDT 上运行查询。

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

Looker 的重新生成器不会自动重新构建使用 persist_for 的 PDT,依赖项级联 PDT 除外。当 persist_for 表是与基于触发器的 PDT(使用 datagroup_triggerinterval_triggersql_trigger_value 持久性策略的 PDT)的依赖项级联的一部分时,重新生成器将监控并重建 persist_for 表,以便在级联中重建其他表。请参阅本页面中的 Looker 如何构建级联派生表部分。

materialized_view: yes

借助具体化视图,您可以利用数据库的功能在 Looker 项目中保留派生表。如果您的数据库方言支持具体化视图,并且您的 Looker 连接配置为启用了启用 PDT 切换开关,那么您可以通过为派生表指定 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。请务必使用 Explain from 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 是一个字面量字符串。

在下一个示例中,clean_events PDT 是根据数据库中的 events 表创建的。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_C,而 TABLE_B 依赖于 TABLE_A。如果 Looker 在缓存中没有针对 TABLE_C 查询的有效结果,则 Looker 会构建查询所需的所有表。因此,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 在用户查询时构建,在 persist_for 间隔时间结束之前一直保留在数据库中,直到用户下次查询它们时才会重新构建。不过,如果 persist_for PDT 是与基于触发器的 PDT(使用 datagroup_triggerinterval_triggersql_trigger_value 持久性策略的 PDT)级联的一部分,则 persist_for PDT 实质上会在其依赖的 PDT 进行重新构建时进行查询。因此,在这种情况下,persist_for PDT 将根据其相关 PDT 的时间表重新构建。这意味着 persist_for PDT 可能会受到其依赖项的持久性策略的影响。

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

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

点击“Explore Actions”按钮可打开“Explore”菜单,您可以从中选择“Rebuild Derived Tables & Run”。

只有拥有 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 托管的实例,如果重新构建派生表的用时超过 1 小时,则该表将无法成功重新构建,并且浏览器会话将会超时。如需详细了解可能影响 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 策略的持久表)或 regenerator 下次运行时(针对使用 datagroup_triggerinterval_triggersql_trigger_value 的持久性表)重新构建该表。

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

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

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

您可以在 Project Health 面板中检查项目中是否包含未构建的 PDT。点击 Looker IDE 中的 Project Health 图标,以打开 Project Health 面板。然后点击验证 PDT 状态按钮。

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

Project Health 面板会显示该项目未构建的 PDT 列表,以及“Go PDT Management”(转到 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 参数和 filters 参数,前者用于过滤出过去 90 天的数据,后者用于过滤出过去 2 年的数据以及前往尤卡谷机场的数据。

dev_filters 参数可与 filters 参数结合使用,以便将所有过滤条件应用于表的开发版。如果 dev_filtersfilters 为同一列指定了过滤条件,则 dev_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 构建,Looker 重新生成器周期的运行频率可能不会按照数据组和 PDT 维护时间表设置中指定的频率运行。其他因素可能会影响重新构建表所需的时间,如本页的实现永久表的重要注意事项部分所述。

如果 PDT 无法构建,重新生成器可能会尝试在下一个重新生成器周期中重新构建表:

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

如果用户在构建时从持久性表请求数据,但查询结果不在缓存中,Looker 将检查现有表是否仍然有效。(如果前一个表与表的新版本不兼容,则可能是无效表。如果新表具有不同的定义、新表使用不同的数据库连接,或者新表是使用不同版本的 Looker 创建的,就可能会发生这种情况。)如果现有表仍然有效,Looker 将从现有表返回数据,直到新表构建完毕。否则,如果现有表无效,Looker 将在重新构建新表后提供查询结果。

实现保留表的重要注意事项

鉴于持久性表(PDT 和汇总表)的实用性,很容易在 Looker 实例上积累许多此类表。可能会造成这样一种场景:Looker 重新生成器需要同时构建多个表。尤其是对于级联表或长时间运行的表,您可以创建如下场景:表在重新构建之前会有很长时间的延迟;或者,当数据库努力生成表时,用户从表获取查询结果会有所延迟。

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

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

  • 您的 Looker 管理员可能已使用数据库连接的数据组和 PDT 维护时间表设置,更改了重新生成器触发检查的时间间隔。
  • Looker 重新生成器在完成上一个周期的所有检查和 PDT 重新构建之前,不会启动新周期。因此,如果您有长时间运行的 PDT 构建,Looker 重新生成器周期可能不如数据组和 PDT 维护时间表设置的频率。
  • 默认情况下,重新生成器可通过连接一次启动一个 PDT 或汇总表的重建。Looker 管理员可以使用连接设置中的PDT 构建器连接数量上限字段,调整重新生成器允许的并发重建数量。
  • 由同一 datagroup 触发的所有 PDT 和汇总表将在同一重新生成过程中重新构建。如果您有许多表使用数据组(直接使用或因级联依赖项而产生),则负载可能非常高。

除前面的注意事项外,在某些情况下,您应该避免向派生表添加持久性功能:

  • 何时extended派生表 - 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 都存在问题,还是只有其中一个方面存在问题。如果其中一个函数存在问题,则问题可能是由 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 所依赖的所有表都没有任何共享或独占锁。为了让 Looker 成功构建 PDT,它需要对要更新的表获取独占锁。这将与表中当前的其他共享或独占锁定冲突。在所有其他锁定都被清除之前,Looker 将无法更新 PDT。Looker 在构建 PDT 时对表上的任何独占锁也是如此;如果表存在独占锁,则在独占锁被清除之前,Looker 无法获取共享锁来运行查询。
  • 使用 SQL Runner 中的 Show Processes 按钮。如果存在大量活跃的进程,则可能会降低查询速度。
  • 监控查询中的注释。请参阅本页面中的查询 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 将使用缓存中的结果。(如需了解其工作原理,请参阅缓存查询文档页面。)
  • 如果结果不在缓存中,并且存在有效的 PDT 版本,Looker 将从数据库中的 PDT 提取结果。
  • 如果数据库中没有有效的 PDT,Looker 将尝试重新构建 PDT。
  • 如果无法重新构建 PDT,Looker 会针对查询返回错误。Looker 重新生成器将在下次查询 PDT 或下次 PDT 的持久性策略触发重新构建时尝试重新构建 PDT。

对于级联 PDT,遵循相同的逻辑,但对于级联 PDT:

  • 如果为一个表构建失败,则无法沿着依赖项链构建 PDT。
  • 从属 PDT 本质上是查询其依赖的 PDT,因此一个表的持久性策略可以触发在链上层的 PDT 重新构建。

回顾之前的级联表示例,其中 TABLE_D 依赖于 TABLE_C,而 TABLE_C 依赖于 TABLE_B,而 TABLE_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_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 上,索引用于生成交错排序键。)