Get record count in Azure DocumentDb

后端 未结 8 1825
孤街浪徒
孤街浪徒 2021-02-03 18:44

It seems like \'select count(*) from c\' in the SQL queries allowed by documentdb in the azure site and through the documentdb explorer (https://studiodocumentdb.codeplex.com/)

8条回答
  •  南笙
    南笙 (楼主)
    2021-02-03 19:20

    I did a test against a partitioned Document db collection with 200K entities in a single partition. The Collection is configured with 10K RU/second.

    Client side queries:

    1. "SELECT VALUE COUNT(1) FROM c"

    Time elapsed (ms): 2471 milliseconds Total Request Units consumed: 6143.35

    Note: This is the fastest and cheapest option. But keep in mind that you would need to handle continuation on the client side and execute next query using the returned continuation token otherwise you may get partial result/count.

    1. "SELECT COUNT(c.id) FROM c"

    Time elapsed (ms): 2589 Total RU: 6682.43

    Note: This is very close but slightly slower and more expensive.

    Server side / Stored Procedure:

    1. If you need a stored proc, there is one provided here: https://github.com/Azure/azure-cosmosdb-js-server/blob/master/samples/stored-procedures/Count.js

    But beware it is problematic.. It internally reads all documents in the collection / partition just to calculate the count. As a result it is much slower and a lot more expensive!

    Time elapsed (ms): 8584 milliseconds Total RU: 13419.31

    1. I updated the stored procedure provided in above link to improve the performance. Full Updated Count.js below. The updated stored proc performs way faster and cheaper than the original and it is on par with the best performing client side query (#1 above):

    Time elapsed (ms): 2534 milliseconds Total RU: 6298.36

    function count(filterQuery, continuationToken) {
        var collection = getContext().getCollection();
        var maxResult = 500000; 
        var result = 0;
    
        var q = 'SELECT \'\' FROM root';
        if (!filterQuery) {
            filterQuery = q;
        }
    
        tryQuery(continuationToken);
    
        function tryQuery(nextContinuationToken) {
            var responseOptions = { continuation: nextContinuationToken, pageSize: maxResult };
    
            if (result >= maxResult || !query(responseOptions)) {
                setBody(nextContinuationToken);
            }
        }
    
        function query(responseOptions) {
            return (filterQuery && filterQuery.length) ?
                collection.queryDocuments(collection.getSelfLink(), filterQuery, responseOptions, onReadDocuments) :
                collection.readDocuments(collection.getSelfLink(), responseOptions, onReadDocuments);
        }
    
        function onReadDocuments(err, docFeed, responseOptions) {
            if (err) {
                throw 'Error while reading document: ' + err;
            }
    
            result += docFeed.length;
    
            if (responseOptions.continuation) {
                tryQuery(responseOptions.continuation);
            } else {
                setBody(null);
            }
        }
    
        function setBody(continuationToken) {
            var body = { count: result, continuationToken: continuationToken };
            getContext().getResponse().setBody(body);
        }
    }
    

提交回复
热议问题