对于超过1000次调用,Azure DocumentDB查询速度很慢

时间:2015-09-29 16:47:37

标签: azure azure-cosmosdb

我正在试用Azure DocumentDB并且一切正常,但是当我将它与Azure表存储进行比较时,当我有超过1000个文档时,阅读文档看起来有点慢。

以下是我的代码:

public class DocumentDBProvider
{
    private static string EndpointUrl = "https://YourDocumentDbName.documents.azure.com:443/";
    private static string AuthorizationKey = "Take this code from your Azure Management Portal";
    private static string DatabaseName = "InterviewDB";
    private static string DocumentCollectionName = "InterviewCollection";

    public async Task<DocumentCollection> CreateDatabaseAndDocumentCollection()
    {
        var client = new DocumentClient(new Uri(EndpointUrl), AuthorizationKey);

        Database database = await client.CreateDatabaseAsync(new Database { Id = DatabaseName });

        DocumentCollection documentCollection = await client.CreateDocumentCollectionAsync(database.CollectionsLink,
                                                                                         new DocumentCollection { Id = DocumentCollectionName }
                                                                                           );
        return documentCollection;
    }

    public string GetDocumentLink()
    {
        var client = new DocumentClient(new Uri(EndpointUrl), AuthorizationKey);
        Database database = client.CreateDatabaseQuery().Where(db => db.Id == DatabaseName).AsEnumerable().FirstOrDefault();
        DocumentCollection documentCollection = client.CreateDocumentCollectionQuery(database.CollectionsLink).Where(db => db.Id == DocumentCollectionName).AsEnumerable().FirstOrDefault();
        return documentCollection.DocumentsLink;
    }
    public DocumentClient GetClient()
    {
        return new DocumentClient(new Uri(EndpointUrl), AuthorizationKey);
    }

    public List<Candidate> GetCandidateById(int candidateId)
    {
        var client = new DocumentClient(new Uri(EndpointUrl), AuthorizationKey);
        Database database = client.CreateDatabaseQuery().Where(db => db.Id == DatabaseName).AsEnumerable().FirstOrDefault();
        DocumentCollection documentCollection = client.CreateDocumentCollectionQuery(database.CollectionsLink).Where(db => db.Id == DocumentCollectionName).AsEnumerable().FirstOrDefault();

        return client.CreateDocumentQuery<Candidate>(documentCollection.DocumentsLink).Where(m => m.CandidateId == candidateId).Select(m => m).ToList();
    }

}

当我调用1000次时,有什么想法可以加载缓慢调用GetCandidateById函数?

2 个答案:

答案 0 :(得分:1)

如果在负载测试或循环中调用此函数(GetCandidateById)超过1000次,我想您可能遇到的性能问题是创建DocumentLink以及DocumentCollection

在DocumentDB中查询文档时 - 应该缓存documentCollection.DocumentsLink值,这样就不必为每个查询查询数据库和集合。

这会将您的查询从3次网络往返减少到1。

答案 1 :(得分:1)

正如Aram所提到的,上面包含的代码片段不会缓存Collection自我链接....所以该方法会产生3个网络请求(1个用于检索数据库,1个用于检索集合,1个用于检索文件)。

缓存集合的自链接可以将方法减少到单个网络请求,从而大大提高了方法的性能。

基于身份验证的路由

由于上面的代码片段通过id检索数据库和集合,我建议的另一个改进是使用基于id的路由...这意味着您可以避免查询集合以检索自链接。

以下是使用自我链接执行文档删除操作的示例:

// Get a Database by querying for it by id
Database db = client.CreateDatabaseQuery()
                    .Where(d => d.Id == "SalesDb")
                    .AsEnumerable()
                    .Single();

// Use that Database's SelfLink to query for a DocumentCollection by id
DocumentCollection coll = client.CreateDocumentCollectionQuery(db.SelfLink)
                                .Where(c => c.Id == "Catalog")
                                .AsEnumerable()
                                .Single();

// Use that Collection's SelfLink to query for a DocumentCollection by id
Document doc = client.CreateDocumentQuery(coll.SelfLink)
                     .Where(d => d.Id == "prd123")
                     .AsEnumerable()
                     .Single();

// Now that we have a doc, use it's SelfLink property to delete it
await client.DeleteDocumentAsync(doc.SelfLink);

这是使用基于id的路由(带有手动构建的字符串)的相同文档删除逻辑:

// Build up a link manually using ids
// If you are building up links manually, ensure that 
// the link does not end with a trailing '/' character
var docLink = string.Format("dbs/{0}/colls/{1}/docs/{2}", 
     "SalesDb", "Catalog", "prd123");

// Use this constructed link to delete the document
await client.DeleteDocumentAsync(docLink);

SDK还包含一个URI工厂,可用于代替手动构建字符串:

// Use UriFactory to build the DocumentLink
Uri docUri = UriFactory.CreateDocumentUri("SalesDb", "Catalog", "prd123");

// Use this constructed Uri to delete the document
await client.DeleteDocumentAsync(docUri);

查看以下博文,了解更多详情:https://azure.microsoft.com/en-us/blog/azure-documentdb-bids-fond-farewell-to-self-links/