具有大量数据的部署的最佳实践

谁应该阅读此文

本文适用于使用 Salesforce 部署的经验丰富的应用程序架构师,这些部署具有以下特点: 包含大量数据。

“大数据量”是一个不精确的弹性术语。如果您的部署有数十个 数千个用户、数千万条记录或数百 GB 的总记录 存储,您拥有大量数据。即使使用较小的部署,您仍然可以 从这些最佳实践中学习一些东西。

要了解本文中涉及 Salesforce 实施细节的部分, 阅读 https://developer.salesforce.com/page/Multi_Tenant_Architecture

概述

Salesforce 使客户能够轻松地将其应用程序从小批量扩展到大量 的数据。这种缩放通常是自动发生的,但随着数据集变大,时间 某些操作所需的增长。架构师设计和配置数据的方式 结构和操作可以将这些操作时间增加或减少几个数量级 大小。受不同体系结构和配置影响的主要进程包括:

  • 直接或集成加载或更新大量记录
  • 通过报告和查询或视图提取数据

优化这些主要流程的策略包括:

  • 遵循行业标准做法,以适应 启用数据库的应用程序
  • 延迟或绕过业务规则和共享处理
  • 选择最有效的操作来完成任务

本文内容

  • 提高具有大量数据的应用程序性能的技术
  • 影响绩效的 Salesforce 机制和实施不太明显 方式
  • Salesforce 机制,旨在支持具有大数据的系统的性能 卷

Salesforce 大对象

Salesforce 提供称为 Big Objects 的大数据技术。一个大对象存储和管理 Salesforce 平台上的大量数据。您可以存档来自其他对象的数据,或者 将来自外部系统的大量数据集整合到一个大对象中,以全面了解您的 客户。一个大对象提供一致的性能,无论您有 100 万条记录,还是 100 条记录 百万,甚至10亿。这种比例赋予了大物体力量并定义了它 特征。

本文重点介绍如何优化存储在标准和自定义对象中的大量数据,而不是 大物体。实现最佳性能和可持续的长期存储解决方案,甚至 较大的数据集,请使用 Bulk API 或 Batch Apex 将数据移动到大型对象中。

基本概念

本部分概述了两个关键概念:多租户和搜索 架构,以解释 Salesforce 如何:

  • 将其应用程序提供给客户的实例和组织
  • 保持受支持的自定义安全、独立和高 执行
  • 跟踪和存储应用程序数据
  • 为该数据编制索引以优化搜索
  • 多租户和元数据概述
  • 搜索体系结构

多租户和元数据概述

多租户是提供单个应用程序的一种方式 到多个组织,例如不同的公司或部门 在公司内部,来自单个软硬件堆栈。而不是 为每个提供一整套硬件和软件资源 组织,Salesforce 在单个实例和每个实例之间插入一层软件 组织的部署。这一层对组织是不可见的, 它们只能看到自己的数据和架构,而 Salesforce 会在后台重新组织数据以执行高效的操作。

多租户要求应用程序能够可靠地运行,即使在 架构师正在进行 Salesforce 支持的自定义,其中包括创建自定义数据对象、 更改接口,并定义业务规则。为确保 特定于租户的自定义不会破坏其他自定义项的安全性 租户或影响其性能,Salesforce 使用运行时引擎从 这些自定义。通过保持架构之间的边界 Salesforce 保护每个租户的数据和操作的完整性。

当组织创建自定义对象时,平台会跟踪元数据 关于对象及其字段、关系和其他对象 定义特征。Salesforce 将所有虚拟表的应用程序数据存储在几个大型表中 数据库表,按租户分区并用作堆 存储。然后,平台的引擎将虚拟表具体化 运行时的数据,通过考虑相应的元数据。

而不是试图管理一个庞大的、不断变化的实际 每个应用程序和租户、平台的数据库结构 存储模型使用一组元数据管理虚拟数据库结构, 数据和数据透视表。因此,如果应用传统的性能调优 基于组织的数据和架构的技术,您可以 可能无法看到您对实际基础数据的预期影响 结构。

注意

作为客户,您也无法优化 SQL 底层 许多应用程序操作,因为它是由系统生成的, 不是由每个租户编写的。

搜索体系结构

搜索是基于自由格式文本查询记录的功能。Salesforce 搜索架构是 基于其自己的数据存储,该数据存储针对搜索该文本进行了优化。Salesforce 提供搜索 在应用的许多领域具有功能,包括:

  • 侧边栏
  • 高级搜索和全局搜索
  • 查找框和查找字段
  • 建议的解决方案和知识库
  • Web-to-Lead 和 Web-to-Case
  • 重复的潜在客户处理
  • 适用于 Apex 和 API 的 Salesforce 对象搜索语言 (SOSL)

对于要搜索的数据,必须首先对其进行索引。索引是使用搜索创建的 索引服务器,这些服务器还会生成和异步处理新 创建或修改的数据。创建或更新可搜索对象的记录后,它会 更新后的文本可能需要大约 15 分钟或更长时间才能变得可搜索。

Salesforce 执行索引 首先在索引中搜索适当的记录,然后缩小范围 基于访问权限、搜索限制和其他过滤器的结果。此过程将创建 结果集,通常包含最相关的结果。结果出来后 集合达到预定大小,剩余的记录将被丢弃。结果集是 然后用于从数据库中查询记录以检索用户 看到。

提示

也可以使用 SOSL 访问搜索,而 SOSL 又可以 使用 API 或 Apex 调用。

适用于大型系统的基础架构 数据卷

本节概述:

  • 直接支持性能的 Salesforce 组件和功能 具有大量数据的系统
  • Salesforce 使用这些组件和功能的情况
  • 最大限度地利用 Salesforce 基础架构的优势的方法
  • Lightning Platform 查询优化器 Salesforce 多租户架构使用底层数据库的方式使得数据库系统的优化器
    无法有效优化搜索查询。Lightning Platform 查询优化器通过在 Salesforce 中提供高效的数据访问来帮助数据库的优化器生成有效的查询。
  • 数据库统计
  • 瘦表
  • 索引
  • 部门

Lightning Platform 查询优化器

Salesforce 多租户架构使用底层数据库的方式是: 数据库系统的优化器无法有效地优化搜索查询。

Lightning Platform 查询优化器帮助数据库的优化器 通过在 Salesforce 中提供高效的数据访问来生成有效的查询。

重要

在可能的情况下,我们更改了非包容性条款,以符合我们的 平等的公司价值观。我们保留了某些条款,以避免对 客户实施。

Lightning Platform 查询优化器适用于自动生成的查询,这些查询可处理 报表、列表视图和 SOQL 查询。优化器还处理依赖于 这些生成的查询。具体来说,优化器:

  • 如果可能,根据 查询
  • 确定从中驱动查询的最佳表(如果没有可用的良好索引)
  • 确定如何对剩余表进行排序以最大程度地降低成本
  • 注入创建高效联接所需的自定义外键值表 路径
  • 影响剩余联接(包括共享联接)的执行计划,以最大程度地减少 数据库输入和输出 (I/O)
  • 更新统计信息

创建高效查询

当您处理大量数据时,构建高效的 SOQL 非常重要 查询、报表和列表视图,它们都依赖于选择性和索引。闪电 平台查询优化器确定 SOQL 查询、报告或 列表视图。通过一些简单的 SOQL 查询,您可以轻松地获得必要的统计信息 确定特定筛选条件是否具有选择性。为选择性字段编制索引后, 具有相关筛选条件的查询可以更高效地执行,并且您的用户可以 更高效。

查看以下测量过滤器选择性的实际注意事项 条件。

确定过滤条件的选择性

为了更好地理解选择性,让我们举个例子。生成 SOQL 查询、报表或 Opportunity 对象的列表视图,该对象是组织中最大的对象之一。你有一个过滤器 条件,例如,仅获取 要从对象获取的行。您的过滤条件是否有足够的选择性,以便优化程序能够 使用可用的索引?WHERE

通过简单的 SOQL 查询,您可以快速获取统计信息,帮助您确定是否 给定字段中的值是选择性的。

使用 SOQL 确定筛选条件的选择性

考虑使用基本一元子句的查询 条件。WHERE

SELECT Id, Name FROM Opportunity
WHERE Stagename = 'Closed Won'

使用您选择的查询工具(例如开发人员控制台查询编辑器),执行 以下查询用于获取与筛选条件的选择性相关的一些统计信息。这 以下是 Stagename 字段的示例查询:

SELECT Stagename, COUNT(id) FROM Opportunity
GROUP BY ROLLUP (Stagename)

结果集显示 Stagename 选择列表字段的每个值的记录分布情况,包括 对象。现在,您拥有了确定过滤器选择性所需的统计数据 涉及 Stagename 字段的条件。

确定更复杂过滤条件的选择性

在类似于上一个查询的查询中使用 示例可以很容易地获得必要的统计数据来评估各种 条件。GROUP BY ROLLUP

下面是具有更复杂筛选条件的查询示例。此查询使用日期 字段 (CloseDate) 以及运算符:AND

SELECT Id, Name FROM Opportunity
WHERE Stagename = 'Closed Won'
AND CloseDate = THIS_WEEK

您已经知道上一个 Stagename 字段的统计信息 查询。获取 CloseDate 字段的相同统计信息(按周分组) 对于每一年,请使用以下查询。

SELECT WEEK_IN_YEAR(CloseDate), CALENDAR_YEAR(CloseDate), COUNT(id)
FROM Opportunity
GROUP BY ROLLUP(WEEK_IN_YEAR(CloseDate),CALENDAR_YEAR(CloseDate))
ORDER BY CALENDAR_YEAR(CloseDate), WEEK_IN_YEAR(CloseDate)

该查询返回有关每周 Opportunity 记录分布的统计信息 每年的 CloseDate。

对于组合了两个或多个条件的过滤条件 (using ),查询优化器在 筛选目标小于:AND

  • 每个过滤器的选择性阈值是两倍
  • 这些字段相交的选择性阈值

对于本主题中的第三个示例,这意味着:

  • Status = ‘Closed Won’是选择性的(49,899 < 150,000)
  • CloseDate = THIS_WEEK是选择性的(~3000 < 150,000)

总体而言,由于这两个原因,过滤条件是选择性的。

如果其中一个筛选条件是非选择性的,例如,对应于 250,000 条记录,则两种可能性可以使 整体过滤条件选择性。Status=’Closed Won’

  • 每个筛选条件对应于少于 300,000 条记录(选择性是 每个过滤器的阈值)
  • 的交集小于 150,000 条记录。Status=’Closed Won’ AND CloseDate = THIS_WEEK

示例中的筛选条件小于 300,000 条记录,因此总体条件为 选择性。

提示

与操作员一起,每个过滤器必须满足 阈值。OR

了解已删除记录对选择性的影响

收集选择性统计信息时,可以使用 布尔字段 IsDeleted。此字段在每个标准和 自定义对象。

使用该函数收集的上一个查询 所有 Opportunity 记录的数据。IsDeleted 是还是 .自 收集 Opportunity.StageName 的选择性统计信息,并显式收集 排除已删除的记录,请尝试以下查询。ROLLUPtruefalse

SELECT Stagename, COUNT(id) FROM Opportunity WHERE IsDeleted=false GROUP BY Stagename

确保字段具有索引

在将查询、报表或列表视图投入生产之前,请确认给定的筛选器 条件是选择性的。但是,使条件具有选择性的字段必须具有索引 要有效。如果没有必要的索引,查询优化器必须执行完全扫描以 获取目标行。该索引有助于提高查询的执行速度,并改进 组织用户的工作效率。

Database Query & Search Optimization 备忘单列出了默认具有索引的标准字段,包括 Id、Name、OwnerId、CreatedDate、SystemModstamp 和 RecordType,以及所有 主从和查找字段。

如果您的筛选条件涉及自定义字段,请与客户支持部门合作,创建一个 筛选器使用的字段的自定义索引。并非所有字段都可以有索引,例如 非确定性公式字段。

数据库统计

现代数据库收集有关存储在其中的数据的数量和类型的统计信息,以及 他们使用此信息来有效地执行查询。由于 Salesforce 的多租户 在软件架构上,平台必须保留自己的一套统计信息 帮助数据库了解访问数据的最佳方式。因此,当大量 使用 API 创建、更新或删除的数据时,数据库必须收集统计信息 在应用程序可以有效地访问数据之前。目前,此统计收集过程 每晚运行。

瘦表

Salesforce 可以创建瘦表来包含常用字段,并 避免联接。这可以提高某些只读操作的性能。瘦桌子 在修改源表时,与源表保持同步。

如果要使用瘦表,请联系 Salesforce 客户支持。启用后,瘦 在适当的情况下自动创建和使用表。您无法创建、访问或 自行修改瘦表。如果要优化报表、列表视图或查询 更改(例如,要添加新字段),您需要联系 Salesforce 以更新您的瘦身 表定义。

瘦表如何提高性能

对于您可见的每个对象表,Salesforce 会在 标准字段和自定义字段的数据库级别。这种分离,是看不见的 当查询包含这两种字段时,客户通常需要联接。一个瘦弱的 表包含这两种类型的字段,并且还省略了软删除的记录。此表显示 Account 视图、相应的数据库表和 可以加快帐户查询速度。

仅引用瘦表中的字段的只读操作不需要额外的 加入,因此可以表现得更好。瘦表对表最有用 包含数百万条记录,以提高只读操作的性能,例如 报告。

重要

瘦桌子不是挥舞性能的魔杖 问题。维护保存实时数据副本的单独表会产生开销。 在不适当的上下文中使用它们可能会导致性能下降,而不是 起色。

可以在自定义对象上创建瘦表,也可以在 Account、Contact、Opportunity、Lead、 和 Case 对象。它们可以增强报表、列表视图和 SOQL 的性能。瘦表可以包含以下类型的字段。

  • 复选框
  • 日期
  • 日期和时间
  • 电子邮件
  • 百分之
  • 电话
  • 选择列表(多选)
  • 发短信
  • 文本区域
  • 文本区域(长)
  • 网址

瘦表和瘦索引也可以包含加密数据。

下面是一个示例,说明瘦表如何加快查询速度。而不是使用日期范围 喜欢 – 这需要 创建年度或年初至今报告的昂贵重复计算 – 您可以 使用瘦表包含 Year 字段并筛选 。01/01/1112/31/11Year = '2011'

考虑

  • 瘦表最多可以包含 100 列。
  • 瘦表不能包含来自其他对象的字段。
  • 对于完整沙盒:瘦表将复制到完整沙盒组织。对于其他 沙盒类型:瘦表不会复制到您的沙盒组织。要有 为完整沙箱以外的沙盒类型激活的生产瘦表,请联系 Salesforce 客户支持。

索引

重要

在可能的情况下,我们更改了非包容性条款,以符合我们的 平等的公司价值观。我们保留了某些条款,以避免对 客户实施。Salesforce 支持自定义索引以加快查询速度,您可以通过以下方式创建自定义索引 联系 Salesforce 客户支持。

注意

Salesforce Customer 的自定义索引 在生产环境中创建的支持将复制到您创建的所有沙盒中 从该生产环境。对于大多数对象,平台在以下字段上维护索引。

  • RecordTypeId
  • 划分
  • 创建日期
  • Systemmodstamp (LastModifiedDate))
  • 名字
  • 电子邮件(用于联系人和潜在客户)
  • 外键关系(查找和大纲-细节)
  • 唯一的 Salesforce 记录 ID,它是每个对象的主键

Salesforce 还支持自定义字段的自定义索引,但多选选择列表、文本除外 区域(长)、文本区域(丰富)、非确定性公式字段和加密文本 领域。

外部 ID 会导致在该字段上创建索引。然后查询优化器 考虑这些字段。您只能在以下字段上创建外部 ID。

  • 自动编号
  • 电子邮件
  • 发短信

要为其他字段类型(包括标准字段)创建自定义索引,请联系 Salesforce 客户支持。

索引表

Salesforce 多租户架构为自定义字段制作基础数据表 不适合索引。为了克服此限制,平台创建了一个索引表 包含数据副本以及有关数据类型的信息。

平台在此索引表上构建标准数据库索引。索引表将上 对索引搜索可以有效返回的记录数的限制。

默认情况下,索引表不包括 null 记录(具有空值的记录)。你 可以与 Salesforce 客户支持合作,创建包含空行的自定义索引。 即使自定义字段上已有自定义索引,也必须显式启用 并重新生成它们以对空值行进行索引。

标准 和自定义索引字段

查询优化器维护一个表,其中包含有关 每个索引中的数据。它使用此表执行预查询,以确定是否使用 index 可以加快查询速度。

为 例如,假设 Account 对象有一个名为 Account_Type 的字段,该字段可以采用值 、 或 ,并且 字段具有自定义索引。LargeMediumSmall

例如,Salesforce 会生成如下查询:

SELECT *
FROM Account
WHERE Account_Type__c = 'Large'

查询优化器对其内部统计信息表执行预查询,以确定数字 在Account_Type字段中的记录。如果此数字超过对象的 10% 总记录数或 333,333 条记录,则查询不使用自定义索引。Large

查询优化器确定索引的用途。标准索引字段如果筛选器匹配的前 100 万条记录少于 30%,并且匹配的 附加记录,最多 100 万条记录。

例如,标准 在以下情况下使用索引:

  • 对包含 200 万条记录的表执行查询,并且筛选器匹配 450,000 条或更少的记录。
  • 对包含 500 万条记录的表执行查询,并且筛选器匹配 900,000 条或更少的记录。

自定义索引字段如果筛选器匹配的记录少于总数的 10%,则使用,最多 333,333 记录。例如,在以下情况下使用自定义索引:

  • 对包含 500,000 条记录的表执行查询,并且筛选器匹配 50,000 条或更少的记录。
  • 对包含 500 万条记录的表执行查询,筛选器 匹配 333,333 条或更少的记录。

如果不满足索引字段的条件,则只会从查询中排除该索引。如果 它们在子句中并满足以下阈值 记录,有时会使用其他索引。WHERE

查询优化器使用类似的注意事项来确定是否使用索引 当子句包含 、 或 .WHEREANDORLIKE

  • 对于 ,查询优化器使用索引 除非其中一个返回对象记录的 20% 以上或总共 666,666 个 记录。AND
  • 对于 ,查询优化器使用索引,除非 它们都返回超过 10% 的对象记录,即总共 333,333 条记录 记录。OR注意子句中的所有字段必须是 为要使用的任何索引编制索引。OR
  • 对于 ,查询优化器不使用其内部 统计表。相反,它会对多达 100,000 条实际数据记录进行采样来决定 是否使用自定义索引。LIKE

可以在确定性公式字段上创建自定义索引。因为有些值会随时间而变化 或者当交易更新相关实体时发生更改,平台无法索引 非确定性公式。

以下是示例 使公式字段具有不确定性的事物。非确定性公式字段可以:

  • 引用其他实体(如可通过查找字段访问的字段)
  • 包括跨其他实体的其他公式字段
  • 使用动态日期和时间函数(例如,和TODAYNOW)

这些公式字段也被视为非确定性字段

  • 所有者、自动编号、部门或审核字段(CreatedDate 和 CreatedByID 字段除外)
    • 对 Lightning Platform 无法索引的字段的引用
    • 多选选择列表
    • 多币种组织中的货币字段
    • 长文本区域字段
    • 二进制字段(blob、文件或加密文本)
  • 具有特殊功能的标准字段
    • 商机:Amount、TotalOpportunityQuantity、ExpectedRevenue、IsClosed、IsWon
    • 案例:ClosedDate、IsClosed
    • 产品:ProductFamily、IsActive、IsArchived
    • 解决方案:状态
    • 线索:状态
    • 活动:Subject、TaskStatus、TaskPriority

注意

如果在创建索引后修改了公式,则会重新生成索引。如果使用跨对象表示法指定,则通常使用跨对象索引,因为它们是 在下文中 例。

SELECT Id
FROM Score__c
WHERE CrossObject1__r.CrossObject2__r.IndexedField__c

您可以使用此方法替换无法自定义索引的公式字段,因为它们 引用其他对象。只要对引用的字段进行索引,跨对象 表示法可以有多个级别。

两列自定义索引

两列自定义索引是 Salesforce 平台的一项特殊功能。它们很有用 对于列表视图以及要使用一个字段选择要显示的记录的情况 和另一个字段对它们进行排序。例如,选择依据和排序依据的“帐户”列表视图可以 在第一列和第二列中使用两列索引。StateCityStateCity当两个字段的组合是查询字符串中的常见筛选器时,两列索引 通常可帮助您对记录进行排序和显示。例如,对于以下 SOQL,其中 出现在伪代码中,两列索引 on 比单索引 on 更有效。

f1__c,f2__cf1__c and f2__c

SELECT Name
FROM Account
WHERE f1__c = 'foo'
     AND f2__c = 'bar'

注意

两列索引与单列索引受到相同的限制,一个 例外。两列索引的第二列中可以有 null,而单列索引可以有 null 值 索引不能,除非 Salesforce 客户支持明确启用该选项以包含 null 值。

区域

划分是对大型数据进行分区的一种手段 部署以减少查询返回的记录数,以及 报告。例如,具有许多客户记录的部署可能 创建名为 、 的部门,并将客户分成更小的组,这些组可能 几乎没有相互关系。USEMEAAPAC

Salesforce 为按部门划分数据提供了特殊支持,这 您可以通过联系 Salesforce 客户来启用 支持。

优化性能的技术

本节概述:

  • 优化 Salesforce 性能的技术
  • 作为基础的安排、特点、机制和选项 这些技术
  • 您应该使用这些技术和定制的情况 他们满足您的需求
  • 使用 Mashup
  • 延迟共享计算
  • 使用 SOQL 和 SOSL
  • 删除数据
  • 搜索

使用 Mashup

减少 Salesforce 中数据量的一种方法是在 其他应用程序,然后根据需要将该应用程序提供给 Salesforce。Salesforce将这样的安排称为 Mashup,因为它提供了两个应用程序的快速、松散耦合的集成。 Mashup 使用 Salesforce 演示文稿来 显示 Salesforce 托管的数据和 外部托管的数据。Salesforce 支持以下功能 Mashup 设计。外部网站Salesforce UI 显示 外部网站,并向其传递信息和请求。通过这种设计,您可以制作 该网站看起来像 Salesforce UI 的一部分。标注Apex 代码允许 Salesforce 使用 用于与外部系统实时交换信息的 Web 服务。

由于其实时性限制,mashup 仅限于短交互和小 数据量。

请参阅 Apex 开发人员指南。

使用混搭的优点

  • 数据永远不会过时。
  • 无需开发专有方法来集成这两个系统。

使用混搭的缺点

  • 访问数据需要更多时间。
  • 功能减少。例如,报告和工作流在外部不起作用 数据。

延迟共享计算

在某些情况下,使用某项功能可能是合适的 称为延迟共享计算,允许用户延迟 在新用户、规则和 其他内容已加载。

组织的管理员可以使用延迟共享 暂停和恢复共享计算的计算权限, 并管理两个流程:组成员资格计算和共享 规则计算。管理员可以暂停这些计算 执行大量配置更改时,可能会 导致非常长的共享规则评估或超时,并恢复 组织维护期间的计算。这 延时可以帮助用户处理大量与共享相关的内容 配置在工作时间内快速更改,然后让 重新计算过程在工作日之间或更长时间内运行一夜之间 一个周末。

使用 SOQL 和 SOSL

SOQL 查询等同于 SQL 语句和 SOSL 查询 是执行基于文本的搜索的编程方式。SELECT

索克尔SOSL公司
执行方式数据库搜索索引
使用query()search()

在以下情况下使用 SOQL:

  • 您知道数据驻留在哪些对象或字段中。
  • 您希望:
    • 从单个对象或多个对象中检索数据 彼此相关
    • 计算符合指定条件的记录数
    • 在查询过程中对结果进行排序
    • 从数字、日期或复选框字段中检索数据

在以下情况下使用 SOSL:

  • 您不知道数据驻留在哪个对象或字段中, 您希望以最有效的方式找到它。
  • 您希望:
    • 高效检索多个对象和字段,以及这些对象 可能彼此相关,也可能不相关
    • 使用以下方法检索组织中特定部门的数据 部门功能,您希望在最有效的位置找到它 可能的方式

使用 SOQL 或 SOSL 时,请考虑以下事项。

  • SOQL 筛选器和 SOSL 搜索查询都可以指定 您应该寻找的文本。当给定的搜索可以使用任何一种语言时,如果搜索表达式 使用术语。WHERECONTAINS
  • SOSL公司 可以标记一个字段中的多个术语(例如,以 spaces),并在此基础上构建搜索索引。如果您正在搜索特定的非 您知道某个字段中存在的术语,您可能会发现 SOSL 在这些搜索中比 SOQL 更快。为 例如,如果出现以下情况,则可以使用 SOSL 您正在针对包含“Paul 和 John”等值的字段搜索“John” 公司”。
  • 在某些情况下,当 SOQL 中使用多个筛选器时,即使可以对子句中的字段进行索引,也无法使用索引。在这种情况下,将单个查询分解为多个查询,每个查询都应有一个筛选器,然后 合并结果。WHEREWHEREWHERE
  • 使用具有选择列表或外键字段的 null 值的筛选器执行查询不会使用索引,应避免使用索引。WHERE为 示例,以下客户查询执行 不好。
SELECT Contact__c, Max_Score__c, CategoryName__c, Category__Team_Name__c
FROM Interest__c
WHERE Contact__c != null
    AND Contact__c IN :contacts
    AND override__c != 0
    AND (
            (override__c != null AND override__c > 0)
            OR
            (score__c != null AND score__c > 0)
        )
    AND Category__c != null
    AND (
            (Category_Team_IsActive__c = true OR CategoryName__c IN :selectvalues)
            AND
            (
                Category_Team_Name__c != null
                AND
                Category_Team_Name__c IN :selectTeamValues
            )
        )

(项目 前面有冒号,例如 ,是 Apex 变量。请参阅使用 Apex 《Apex 开发人员指南》中的 SOQL 和 SOSL 查询中的变量。 在标准中阻止了索引的使用,并且一些 这些条件是多余的,导致执行时间增加。设计数据模型,使其不依赖于有效字段 值。

:contactsNullsnulls

可以重写查询 如:

SELECT Contact__c, Max_Score__c, CategoryName__c, Category_Team_Name__c
FROM Interest__c
WHERE Contact__c IN :contacts
    AND (override__c > 0 OR score__c > 0)
    AND Category__c != 'Default'
    AND (
            (Category_Team_IsActive__c = true OR CategoryName__c IN :selectvalues)
            AND
            Category_Team_Name__c IN :selectTeamValues
        )

为 字段 Category__c,该值被替换为 ,允许索引为 用于该字段。DefaultNULL

再举一个例子,如果动态值用于 WHERE 字段,并且可以传入 null 值,则不要让查询 运行以确定没有记录;相反,如果可能,请检查 null 值并避免查询。按帐户的外键帐号检索帐户的查询可能如下所示 this(在伪代码中)。

SELECT Name
   FROM Account
   WHERE Account_ID___c = :acctid;

if (rows found == 0) return "Not Found"

如果 acctid 为 ,则逐行扫描整个 Account 表,直到检查所有数据。null最好重写 代码 如:

if (acctid != null) {
   SELECT Name
      FROM Account
      WHERE Account_Id___c = :acctid
}
else {
    return "Not Found"
}
  • 在设计自定义查询搜索用户界面时,它是 重要的是:
    • 将要搜索或查询的字段数保持在最低限度。使用许多字段会导致许多排列,这可能很难调整。
    • 确定 SOQL、SOSL 或两者的组合是否适合搜索。

删除数据

Salesforce 数据删除机制可以对大型 数据量。Salesforce 使用回收站隐喻用户删除的数据。相反 删除数据时,Salesforce 会将数据标记为已删除,并通过 回收站。此过程称为软删除。当数据被软删除时,它 仍然会影响数据库性能,因为数据仍处于驻留状态,而已删除的记录具有 从任何查询中排除。

数据在回收站中保留 15 天,或直到回收站增长到特定的 大小。然后在 15 天后从数据库中硬删除数据;当大小限制 达到;或者当使用 UI、API 或 Apex 清空回收站时。

此外,Bulk API 和 Bulk API 2.0 支持硬删除选项,该选项允许 记录以绕过回收站并立即可供删除。我们建议 使用批量 API 2.0 的硬删除功能删除大量数据。

如果要立即删除沙盒组织的自定义对象中的记录, 您可以尝试截断这些自定义对象。您可以联系 Salesforce 客户支持 以获取有关此任务的帮助。

搜索

当添加或更改大量数据时,搜索系统 必须先对该信息编制索引,然后才能进行搜索 由所有用户提供,此过程可能需要很长时间。

请参阅搜索体系结构。

最佳实践

本部分列出了实现良好性能的最佳实践 在具有大量数据的部署中。

在大型 Salesforce 部署中进行性能调优的主要方法依赖于减少系统的记录数 必须处理。如果检索到的记录数足够少, 平台可能使用标准数据库结构,如索引或 非规范化以加快数据检索速度。减少记录数量的方法包括:

  • 通过编写狭窄或选择性的查询来缩小范围例如,如果 Account 对象包含已分发的帐户 均匀地跨所有州,然后按以下方式汇总帐户的报告 单个州的城市范围要广得多,并且需要更长的时间才能 执行 – 而不是按单个帐户汇总帐户的报表 城市在一个州。
  • 减少保持活动状态的数据量例如,如果您的 数据量不断增加,性能会随着时间的推移而下降 由。以相同的速率存档或丢弃数据的策略,其中 它进入系统可以防止这种影响。

这些表格列出了主要目标和要遵循的最佳实践 以实现这些目标。

  • 报告
  • 从 API 加载数据
  • 从 API 中提取数据
  • 搜索
  • SOQL 和 SOSL
  • 删除数据
  • 常规

报告

目标最佳实践
通过以下方式最大限度地提高报告性能:对数据进行分区以匹配其可能的用途最小化每个对象的记录数减少要查询的记录数 – 使用 要对查询进行分段的数据。例如,仅查询单个 状态而不是所有状态。(请参阅分部。
减少联接次数尽量减少以下数量:报告中查询的对象用于生成报表的关系在可行时对数据进行非规范化 — “过度非规范化” 数据会导致更多的开销。使用存储在 报表的父记录。这种做法比 让报表汇总子记录。
减少返回的数据量减少查询的字段数 – 仅添加字段 添加到报表、列表视图或 SOQL 查询 这是必需的。
减少记录数 查询通过存档未使用的记录来减少数据量 — 移动 未使用的记录到自定义对象表中,以减小 Report 对象。使用强调使用标准或自定义的报表筛选器 索引字段。尽可能在报表筛选器中使用索引字段。

从 API 加载数据

目标最佳实践
提高性能任何包含超过 2,000 条记录的数据操作都非常适合 批量 API 2.0,用于成功准备、执行和管理使用批量框架的异步工作流。记录少于 2,000 条的作业 应涉及 REST 中的“批量”同步调用(例如,Composite) 或 SOAP。
使用最高效的 操作使用尽可能快的操作 — 最快、是下一个,以及之后是下一个。如果可能,还分为两个操作:和 .insert()update()upsert()upsert()create()update()使用批量 API 2.0 时,请确保在加载之前数据是干净的。中的错误 批处理会触发该批处理的单行处理,并且该处理量很大 影响性能。
减少要传输和处理的数据更新时,仅发送已更改的字段(仅增量加载)。
缩短传输时间,并 中断对于自定义集成:每次加载一次身份验证,而不是对每条记录进行身份验证。使用 GZIP 压缩和 HTTP 保持活动状态来避免在长时间保存期间丢失 操作。
避免不必要的开销对于自定义集成,每次加载进行一次身份验证,而不是对每条记录进行身份验证。
避免计算在初始加载期间使用公共读/写安全性,以避免共享计算 开销
减少计算如果初始加载可能,请在填充共享规则之前填充角色。将用户加载到角色中。与所有者一起加载记录数据,在角色中触发计算 等级制度。配置公共组和队列,并让这些计算 传播。一次添加一个共享规则,让每个规则的计算完成 在添加下一个之前。如果可能,请在创建和分配组和队列之前添加人员和数据。加载新用户和新记录数据。(可选)加载新的公用组和队列。一次添加一个共享规则,让每个规则的计算完成 在添加下一个之前。
延迟计算并加快负载吞吐量在加载期间禁用 Apex 触发器、工作流规则和验证;探讨 加载完成后使用批处理 Apex 处理记录。
在高效的批量大小与潜在的超时之间取得平衡使用 SOAP API 时,请使用尽可能多的批处理,最多 200 – 在以下情况下仍可避免网络超时:记录很大。保存操作需要大量无法延迟的处理。
优化 Lightning 平台 Web 服务连接器 (WSC) 以使用 Salesforce的使用 WSC 而不是其他 Java API 客户端,如 Axis。
最大程度地减少父记录锁定冲突更改子记录时,按父记录对它们进行分组 – 按 字段 ParentId,以最大程度地减少锁定 冲突。
延迟共享计算使用延迟共享计算权限将共享计算推迟到以下日期 加载所有数据后。(请参阅延迟共享计算。
避免将数据加载到 Salesforce 中使用混搭创建应用程序的耦合集成。(请参阅使用 Mashup。

从 API 中提取数据

目标最佳实践
使用最高效的操作使用 和 SOAP API 每隔一段时间将外部系统与 Salesforce 同步 大于 5 分钟。使用出站消息传递功能进行更频繁的同步。getUpdated()getDeleted()使用可返回超过 100 万个结果的查询时,请考虑使用 批量 API 2.0 的查询功能,这可能更合适。

搜索

目标最佳实践
减少要返回的记录数保持搜索具体,并尽可能避免使用通配符。 例如,使用 而不是 搜索 。MichaelMi*
减少联接次数使用单对象搜索可提高速度和准确性。
提高效率使用设置区域进行搜索以启用语言优化, 并打开增强的查找和自动完成功能以获得更好的性能 在查找字段上。
提高搜索性能在某些情况下,使用除法对数据进行分区。(请参阅分部。
减少索引插入和更新所需的时间 大数据量请参阅搜索体系结构。

SOQL 和 SOSL

目标最佳实践
当具有多个筛选器的 SOQL 查询无法使用索引时,允许索引搜索WHERE分解查询。如果在子句中使用两个由 an 连接的索引字段,则搜索 结果可能超过索引阈值。将查询拆分为两个查询,并联接 结果。ORWHERE
避免对实时计算的公式字段进行查询如果必须查询公式字段,请使用公式。避免使用公式字段进行筛选 包含动态的、不确定的引用。见标准 和自定义索引字段。
对于给定的搜索,使用最合适的语言 SOQL 或 SOSL请参阅使用 SOQL 和 SOSL。
在筛选器中执行具有 null 值的查询 选择列表或外键字段WHERE使用 to 替换选项等值。(请参阅使用 SOQL 和 SOSL。NANULLS
设计高效的自定义查询和搜索用户界面在适当的情况下使用 SOQL 和 SOSL,保持查询的重点,并尽量减少数量 正在查询或搜索的数据。(请参阅使用 SOQL 和 SOSL。
构建高效的 SOQL 和 SOSL 查询在查询中使用筛选器和特定术语。对于 SOQL:使用选择性筛选器,以减少查询优化器的行数 进行扫描。例如,使用引用索引字段和 具有更广泛的可能值。如果筛选器没有选择性,则优化程序 不使用索引列。筛选 和 时,请改用该字段。例如FirstNameLastNameNameSelect id, Email from Lead where Name=’Sam Kennedy’避免使用负滤镜。例如,或status !=’failed’status != NULL使用而不是一大堆语句。例如。INORid in (‘001xxx’,‘001xxy’, ‘001xxz’)避免使用跨对象引用公式字段。不要筛选这些对象。他们 不可索引。对于 SOSL:对于 SOSL,选择性过滤器可减少不相关结果的数量。如果 过滤器不是选择性的,搜索词匹配超过 2,000 个 记录、结果可能会受到搜索拥挤的影响。不要为不想搜索的自定义对象编制索引。它增加了这个数字 可供搜索的记录,这可能导致搜索拥挤。过滤掉您不想搜索的对象。使用特定的搜索词。使用有针对性的搜索组。搜索组包括 NAME、EMAIL 和 PHONE 领域。例如 FIND ‘Avery Smith’ IN NAME FIELDS RETURNING Account(Id,Name), Lead(Id,Name)
避免大型 SOQL 查询超时优化 SOQL 查询,缩小查询范围,并使用选择性筛选器。考虑使用 批量 API 2.0 与批量 API 2.0 查询。如果您已经使用了前面的建议,并且仍然 get timeouts,考虑添加一个 LIMIT 子句(开始 有 100,000 条记录)添加到您的查询中。如果使用批处理 Apex 进行查询,请使用 链接以获取记录集(使用 LIMIT)或考虑将过滤器逻辑移动到 execute 方法。

删除数据

目标最佳实践
删除大量数据删除大量数据时,涉及删除 100 万或 更多记录,请使用 Bulk API 或 Bulk API 2.0 的硬删除选项。删除大 由于删除过程的复杂性,数据量可能需要大量时间。 (请参阅删除数据。
使数据删除过程更加高效删除具有多个子项的记录时,请先删除子项。

常规

目标最佳实践
避免共享计算避免任何用户拥有超过 10,000 条记录。
提高性能使用将数据分散到多个数据分层的策略 对象,并根据需要从另一个对象或外部引入数据 商店。
减少创建完整生产拷贝所需的时间 具有大量数据的沙箱创建生产沙箱的副本时,如果不需要,请排除字段历史记录,并且 在创建沙盒副本之前,不要更改大量数据。
提高部署效率分发子记录,使父级的子记录不超过 10,000 个。例如,在具有许多联系人但不使用 帐户,设置多个虚拟帐户并在它们之间分配联系人。

大数据量案例研究

本节包含:

  • 客户遇到的与大数据量相关的问题
  • 客户使用或可能使用的解决方案来解决这些问题

要识别和解决类似问题,请阅读以下案例研究:

  • 数据聚合
  • 自定义搜索功能
  • 使用 Null 值建立索引
  • 呈现具有大量数据的相关列表
  • API 性能
  • 查询的排序优化
  • 多联接报表性能

数据聚合

情况

客户需要使用标准报告汇总月度和年度指标。这 客户的月度和年度详细信息存储在自定义对象中,其中包含 400 万和 分别为 900 万条记录。这些报告汇总了数百万条记录 在这两个对象中,性能都不是最佳。

解决方案

解决方案是创建一个聚合自定义对象,该对象汇总了每月和每年的 值转换为所需报告所需的格式。然后执行报告 聚合的自定义对象。使用批处理 Apex 填充摘要对象。

自定义搜索功能

情况

客户需要搜索 使用特定值跨多个对象的大量数据量 和通配符。客户创建了一个自定义 Visualforce 页面 这将允许用户输入 1-20 个不同的字段,并且 然后使用 SOQL 进行搜索 这些字段的组合。搜索优化变得困难 因为:

  • 当输入许多值时,子句很大且难以调整。引入通配符时, 查询花费的时间更长。WHERE
  • 有时需要跨多个对象进行查询才能满足 整体搜索查询。这种做法导致了多个查询 发生,从而扩展了搜索范围。
  • SOQL 并不总是适用于所有查询类型。

解决 方案

解决方案是:

  • 仅使用必要的搜索字段来减少字段数量 可以搜索。限制同时字段的数量 可以在对常见用例进行单次搜索期间使用 允许 Salesforce 使用索引进行调整。
  • 将多个对象中的数据非规范化为单个对象 自定义对象,以避免进行多次查询调用。
  • 动态确定 SOQL 的使用 或 SOSL 执行基于 搜索的字段数和输入的值类型。例如,非常 特定值(即无通配符)使用 SOQL 进行查询,这允许索引 以提高性能。

使用 Null 值建立索引

情况

客户需要允许 null 值 并能够对它们进行查询。因为单列 选择列表和外键字段的索引排除了其中 索引列等于 null,则不能使用索引 对于 null 查询。

解决方法

最佳做法是 最初不使用 null 值。如果您发现自己处于类似的状态 情况下,请使用其他字符串,例如 代替 。如果不能这样做,可能是因为记录已经存在于 具有 NULL 值的对象,创建一个公式字段,该字段显示 null 值的文本,然后为该公式字段编制索引。N/ANULL

例如 假设 Status 字段已编制索引并包含 null 值。发出 SOQL 查询 与以下内容类似,可防止使用索引。

SELECT Name
FROM Object
WHERE Status__c = ''

相反,您可以创建公式 叫。

Status_Value

Status_Value__c = IF(ISBLANK(Status__c), "blank", Status__c)

查询时可以索引和使用此公式字段 为 null 值。

SELECT Name
FROM Object
WHERE Status_Value__c = 'blank'

这个概念可以 扩展为包含多个字段。

SELECT Name
FROM Object
WHERE Status_Value__c = '' OR Email = ''

呈现具有大量数据的相关列表

重要

在可能的情况下,我们更改了非包容性条款,以与我们公司保持一致 平等的价值。我们保留了某些条款,以避免对客户产生任何影响 实现。

情况

客户拥有数十万条帐户记录和 1500 万张发票,这些发票是 在自定义对象中,与客户保持主从关系。每个帐户记录 由于发票相关列表的渲染时间过长,因此需要很长时间才能显示 时间。

溶液

显示发票相关列表的延迟与数据倾斜有关。虽然大多数帐户 记录的发票记录很少,有些记录有数千条发票记录。

为了减少延迟,客户尝试减少这些发票记录的数量 父对象,并将子对象中的数据倾斜度保持在最低限度。使用启用分离 加载相关列表设置允许在 客户正在等待相关列表查询完成。

API 性能

情况

客户设计了一个自定义集成,用于将 Salesforce 数据与外部客户同步 应用。集成过程涉及:

  • 在 Salesforce 中查询 给定对象
  • 将此数据加载到外部系统中
  • 再次查询 Salesforce 以获取 所有数据的 ID,以便集成过程可以确定已删除哪些数据 来自Salesforce

这些对象包含数百万条记录。该集成还使用了特定的 API 用户 这是共享层次结构的一部分,用于限制检索到的记录。查询正在采取 分钟即可完成。

在Salesforce中,共享是一种非常 强大的机制,使某些记录对特定用户可见,并且效果很好 用于 UI 交互。但是,当在 SOQL 查询中用作大量数据筛选器时,性能可能会受到影响 由于使用共享作为筛选器时,数据访问更加复杂且难以处理, 特别是当您尝试在大量数据的情况下过滤掉记录时。

溶液

解决方案是授予查询对所有数据的访问权限,然后使用选择性筛选器 以获取适当的记录。例如,使用管理员作为 API 用户将具有 提供了对所有数据的访问,并阻止了在查询中考虑共享。

另一个解决方案是创建一个增量提取,降低 需要处理的数据。

您可以在共享体系结构指南中找到有关共享如何影响性能的详细信息。

查询的排序优化

情况

客户有以下几点 查询。

SELECT Id,Product_Code__c
FROM Customer_Product__c
WHERE CreatedDate = Last_N_Days:3

查询是 查找过去三天内创建的所有记录,但 对象中的数据量超出了标准索引的阈值: 记录总数的 30%,最多 100 万条记录。执行的查询 不好。

溶液

查询重写为:

SELECT Id,Product_Code__c
FROM Customer_Product__c
WHERE CreatedDate = Last_N_Days:3
ORDER BY CreatedDate LIMIT 99999

在此查询中, 未进行阈值检查,并使用索引来查找记录。这种 的查询最多返回 99,999 条记录,顺序如下 在过去三天内创建,假设 99,999 或更少 记录是在过去三天内创建的。CreatedDate

注意

通常 查询已通过 添加的数据时,如果指定对索引字段的查询 如果限制少于 100,000 条记录,则索引用于执行查询。Last_N_DaysORDER BYORDER BY

多联接报表性能

情况

客户创建了报表 使用四个相关对象:客户 (314,000)、销售订单 (769,000)、 销售详细信息(230 万)和帐户所有权(120 万)。 报表几乎没有过滤,需要优化。

溶液

为了优化报告,客户:

  • 添加了其他筛选器,使查询更具选择性和 确保尽可能多的过滤器可转位
  • 尽可能减少每个对象中的数据量
  • 使回收站保持清空。回收站中的数据会影响查询性能。
  • 确保四个相关的共享规则不存在复杂的共享规则 对象。复杂的共享规则可能会对性能产生明显影响。

总结

Salesforce平台是一个强大的环境,其中本机和自定义 应用程序可以非常快速地扩展到大量数据,而 继续保持良好表现。您可以通过以下方式最大限度地发挥这些功能的优势:

  • 使查询具有选择性 – 确保报表、列表视图、 和 SOQL 正在使用适当的过滤器。
  • 减少活动数据量 — 使用存档、混搭、 以及其他技术来减少存储在 Salesforce 中的数据量。

遵循这两个广泛的原则和最佳实践 支持它们可以减少大数据量对 Salesforce 应用程序性能的影响。