CosmosDB有关使用_ts和OrderBy

时间:2018-08-02 15:34:35

标签: azure azure-cosmosdb azure-cosmosdb-sqlapi

我在与文档数据库(相对于图形数据库)有关的CosmosDB查询性能/索引方面遇到问题。我正在使用C#和最新的Nuget版本的SDK。我有一个查询,似乎没有正确使用索引,我不知道为什么。作为参考,这是要查询的文档的结构:

internal class MeetingFeedLastChange
{
    public MeetingFeedLastChange() { }

    [JsonProperty(PropertyName = "partitionKey")]
    public string UserId { get; set; }

    [JsonProperty(PropertyName = "id")]
    public string Id { get; set; }

    [JsonProperty(PropertyName = "meetingId")]
    public string MeetingId { get; set; }

    [JsonProperty(PropertyName = "_etag")]
    public string ETag { get; set; }

    [JsonProperty(PropertyName = "createDate")]
    [JsonConverter(typeof(UTCDateTimeOffsetConverter))]
    public DateTimeOffset CreateDate { get; set; }

    [JsonProperty(PropertyName = "_ts")]
    public Int64 TimeStamp { get; set; }

    [JsonProperty(PropertyName = "documentType")]
    public DocumentType DocumentType { get { return DocumentType.MeetingFeedLastChange; } }
}

这是我正在执行的查询:

var documents = await QueryAsync(client.CreateDocumentQuery<MeetingFeedLastChange>(MessagingCollectionUri, queryOptions)
                    .Where(m => m.UserId == userId && m.DocumentType == DocumentType.MeetingFeedLastChange && m.TimeStamp > syncToken)
                    .OrderBy(m => m.TimeStamp), null);

QueryAsync方法仅执行查询并执行一些性能日志记录。请注意,我正在使用系统生成的_ts字段来确定自上次执行此查询以来是否有任何文档已更改。这是将增量更改向下同步到客户端的非常方便的方法。该查询的执行频率很高,最近我开始收到数据库限制警报。我的记录表明,此查询的RU / s费用比类似查询高10倍。如果我将QueryOptions.PopulateQueryMetrics设置为true并传递一个非常大的syncToken值(例如long.MaxValue),则由于没有实际返回的结果,我希望此查询能够快速执行。但是,我看到它正在击中许多文档(即使它没有返回它们),并且我认为这很可能是因为它没有为查询使用索引:

enter image description here

有趣的是,如果我将查询的OrderBy部分更改为任何其他属性(字符串,数字或日期),或者将其全部删除,则使用索引,这样我会得到更理想的结果:

var documents = await QueryAsync(client.CreateDocumentQuery<MeetingFeedLastChange>(MessagingCollectionUri, queryOptions)
                    .Where(m => m.UserId == userId && m.DocumentType == DocumentType.MeetingFeedLastChange && m.TimeStamp > syncToken)
                    .OrderBy(m => m.DocumentType), null);

enter image description here

我最初的想法是,这可能是由于缺少索引所致。我检查了索引设置,似乎应该对所有属性都进行索引,并且应该使用适当的Range类型(而不是可能导致order by问题的Hash类型)对数字进行索引。同样有趣的是,我认为大于比较(m.TimeStamp> syncToken)还将在_ts字段上使用范围索引,因此似乎存在适用于_ts属性的范围索引,但仅适用于>或<比较,但不是OrderBY(这似乎很奇怪)。

enter image description here

所以,我的问题是:如何调整索引以包含_ts属性,以便我的OrderBy查询能够使用索引而不是进行扫描?

0 个答案:

没有答案