cosmosdb中pyspark的高效查找

cosmosdb中pyspark的高效查找,pyspark,azure-cosmosdb,azure-databricks,Pyspark,Azure Cosmosdb,Azure Databricks,在spark的工作中,我需要从cosmosdb中检索大约20000个文档的数据,这些文档的ID和分区键我都知道 我当前的代码速度非常慢,它准备了一个查询SELECT*FROM c,其中c.pkey=%{pkey}i和c.id in(%{ids}s),我有一个循环来顺序查询cosmosdb,在这个查询中注入来自同一分区的~500到1000个id。(然后使用联合来组装数据帧) 每一个查询都需要30秒到一分钟的时间。在SQLServer中速度会快得多,我不知道发生了什么。(我应该补充一点,这些查询最多

在spark的工作中,我需要从cosmosdb中检索大约20000个文档的数据,这些文档的ID和分区键我都知道

我当前的代码速度非常慢,它准备了一个查询
SELECT*FROM c,其中c.pkey=%{pkey}i和c.id in(%{ids}s)
,我有一个循环来顺序查询cosmosdb,在这个查询中注入来自同一分区的~500到1000个id。(然后使用联合来组装数据帧)

每一个查询都需要30秒到一分钟的时间。在SQLServer中速度会快得多,我不知道发生了什么。(我应该补充一点,这些查询最多只能容纳50k的集合(或现在称之为容器),这非常令人惊讶)

我怎样才能更有效地做到这一点

编辑:代码示例

for pil in partitionedIdsLists :
  for idsList in pil[1] :
    idsEtabsString = r'"'+r'","'.join(idsList)+r'"'
    part_df = spark\
                .read\
                .schema(schema_df)\
                .format("com.microsoft.azure.cosmosdb.spark")\
                .options(
                  **readConfigET, 
                  query_custom = r'SELECT * FROM c WHERE c["pkey"] = %(pkey)i AND c["id"] in (%(listeIds)s)'%{'pkey' : pil[0], 'listeIds' : idsEtabsString}
                )\
                .load()\
                .distinct()

    if full_df is None :
      full_df = spark\
                  .createDataFrame([], schema_df)

    full_df = full_df\
                .union(part_df)

PartitionedDSList是一个夫妻列表
(pkey,[[id1,…,id500],[id501,…,id1000])

首先确保您拥有最新版本:-版本1.2.2之前的任何东西都有糟糕的性能

您不必在每个分区上循环—一次读取(将在工作区上扩展)将是最有效的。Spark应该为每个cosmosdb分区创建一个作业,但是您已经手动计算了这个作业,现在正在连续运行它们,这将一次只消耗集群上的一个内核。如果你有很多分区,这将是糟糕的性能

如果您的ID列表很长(数千个以上),那么我可以看到这也是一个问题。假设您没有其他选择它们的方法,我将首先使用相同的分区键将它们写入cosmosdb,然后加入您的sql查询。假设您对齐分区,这应该是非常有效的

我看不到你在读配置。但使用不同的页面大小:
还有,为什么会有明显的差异?如果您在选择列表中有id,则不可能获得重复的id?您是否在没有使用distinct的情况下进行了测试?

您可以发布一个代码示例吗?您使用的是哪种连接器?@simon_Dmoria使用代码示例编辑,连接器是azure_cosmosdb_spark 2.4.0 2.11I使用的是最新版本。今天早上我添加了分区键,它确实比我昨天没有分区键时的尝试要慢,我将反转它。(并删除明显的)我会尝试更改页面大小并返回给您。老实说,页面大小的影响最小。这些清单上有多少项目?哦,你说的是500-1000。这太多了——我会先用分区编写它们,然后加入它们。两种都试试。将ID列表放入带有partitionid的数据帧中,并将该数据帧写入cosmosdb中的另一个集合。然后在“选择”中的两列上进行连接。或者,你可以不把它写在cosmosdb上,而是广播它,然后加入spark。是的,对不起,你是对的。不过,pyspark连接应该仍然更好。今天下午晚些时候,我将用一些示例代码更新我的答案