SQL 缓慢的外部应用尝试从 2 个分片表读取

问题描述 投票:0回答:1

我有 2 个表中的联系人列表。我的查询只会从 2 个表中的 1 个返回 1 行,基于此,我想要的其他数据将来自特定的其他表。

我有一个可以运行的查询,但运行时间超过 30 秒,我认为这是因为 SQL 试图加载比它需要的更多的数据。

SELECT fe.Id as SubmitionId, 
       fe.Created, 
       case when ci1.contactId is null then ci0.contactId else ci1.contactId end as [ExperienceProfileContactId], 
       case when ci1.contactId is null then cfCustom0.FacetData else cfCustom1.FacetData end as CustomFacetData,
       case when ci1.contactId is null then cf0.FacetData else cf1.FacetData end as PersonalFacetData
from [sitecore_forms_storage].[FormEntries] fe
     outer apply (select top 1 contactId from [Sitecore_Xdb.Collection.Shard0].[xdb_collection].[ContactIdentifiers] cii0 where replace(fe.contactid,'-', '') = cii0.[Identifier]) as ci0
     outer apply (select top 1 contactId from [Sitecore_Xdb.Collection.Shard1].[xdb_collection].[ContactIdentifiers] cii1 where replace(fe.contactid,'-', '') = cii1.[Identifier]) as ci1
     left outer join [Sitecore_Xdb.Collection.Shard0].[xdb_collection].[ContactFacets] cf0 on ci0.ContactId = cf0.ContactId and cf0.FacetKey = 'Personal'
     left outer join [Sitecore_Xdb.Collection.Shard1].[xdb_collection].[ContactFacets] cf1 on ci1.ContactId = cf1.ContactId and cf1.FacetKey = 'Personal'
     left outer join [Sitecore_Xdb.Collection.Shard0].[xdb_collection].[ContactFacets] cfCustom0 on ci0.ContactId = cfCustom0.ContactId and cfCustom0.FacetKey = 'CustomData'
     left outer join [Sitecore_Xdb.Collection.Shard1].[xdb_collection].[ContactFacets] cfCustom1 on ci1.ContactId = cfCustom1.ContactId and cfCustom1.FacetKey = 'CustomData'
WHERE FormDefinitionId = '19847d65-971d-4aa9-bc11-7c0c97fc4e0f'

FormEntries 表将根据末尾的 where 子句返回大约 10 行。以下查询将在不到一秒的时间内返回:

SELECT * 
FROM [sitecore_forms_storage].[FormEntries] fe
WHERE FormDefinitionId = '19847d65-971d-4aa9-bc11-7c0c97fc4e0f'

以下 SQL 在不到一秒的时间内返回,是外部应用程序应该执行的操作的示例:

SELECT TOP 1 contactId 
FROM [Sitecore_Xdb.Collection.Shard1].[xdb_collection].[ContactIdentifiers] cii0 
WHERE '03CB66D16C3842FD94A2E75C4B0A26BA' = cii0.[Identifier]

标识符仅存在于 shard0 或 shard1 的 ContactIdentifiers 表中。

如果标识符位于 shard1 的 ContactIdentifiers 表中,那么我需要查看 shard1 的 ContactFacets 表。否则查看 shard0 的 ContactFacets 表。这个逻辑意味着我真的不需要外部连接其他分片的 ContactFacets 表...但我不确定如何有条件地包含它。

检索构面也很快,因为以下查询应该在整个查询的每行运行一次,并且对其他构面执行类似的查询(即大约 20 次。)它也基本上立即返回:

SELECT FacetData
FROM [Sitecore_Xdb.Collection.Shard1].[xdb_collection].[ContactFacets]
WHERE ContactId = '526104FA-A5CF-0000-0000-06EC10C433D8'
  AND FacetKey = 'Personal'

联系人也可能不在任何一个分片中。在这种情况下,我只希望最后 3 列为空,不需要查看任何一个 ContactFacets 表。

有没有办法加快这个查询速度?

sql sql-server query-optimization outer-join outer-apply
1个回答
0
投票

这不是我正在寻找的解决方案,但根据评论,它在速度上有了巨大的提高。

我仍然有兴趣找到一种仅在另一个外连接/应用返回值时才连接表的方法。

我将 FROM 子句的第一行更改为以下内容,以强制 REPLACE 函数在较小的数据集上运行,因为 [FormEntries] 只有 10 行,而两个 [ContactIdentifiers] 表都有数千行:

from (select Id, FormDefinitionId, Created, replace(contactid,'-', '') as contactid
      from [sitecore_forms_storage].[FormEntries]) fe
     outer apply (select top 1 contactId from [Sitecore_Xdb.Collection.Shard0].[xdb_collection].[ContactIdentifiers] cii0 where fe.contactid = cii0.[Identifier]) as ci0
     outer apply (select top 1 contactId from [Sitecore_Xdb.Collection.Shard1].[xdb_collection].[ContactIdentifiers] cii1 where fe.contactid = cii1.[Identifier]) as ci1
© www.soinside.com 2019 - 2024. All rights reserved.