Skip to content
This repository was archived by the owner on May 7, 2026. It is now read-only.
This repository was archived by the owner on May 7, 2026. It is now read-only.

Too slow query fetch #150

Closed
Closed

Description

@umax

Hi, team!

Imagine we have an entity Order with customer_id (str, uuid4), created_at (datetime) and other fields. I want to get all orders for specified customer and time range.

The query returns about 1500 records.
The problem: it takes about 7-8 seconds!

Environment details

  • OS type and version: Docker image python:3.8-slim
  • Python version: Python 3.8.6
  • pip version: 20.2.2
  • google-cloud-datastore version: 2.0.1

Datastore indexes:

  • kind: Order
    properties:

    • name: customer_id
    • name: created_at
      direction: asc
  • kind: Order
    properties:

    • name: customer_id
    • name: created_at
      direction: desc

Code example

query = db_client.query(
    kind='Order',
    filters=(
        ('customer_id', '=', customer_id),
        ('created_at', '>=', datetime_from),
        ('created_at', '<=', datetime_to),
    ),
)
result = list(query.fetch())

What I do wrong or can you suggest how to speed up this query?
Thanks!

Activity

  1. added
    priority: p2Moderately-important priority. Fix may not be included in next release.
    type: questionRequest for information or clarification. Not an issue.
    on Jan 29, 2021
  2. self-assigned this
    on Feb 2, 2021
  3. tseaver commented on Feb 2, 2021

    @tseaver
    Contributor

    @umax In order to optimize query performance, you need to create composite indexes for the various queries your application makes.

    Per the Datastore docs on index configuration:

    Firestore in Datastore mode uses indexes for every query your application makes. These indexes are updated whenever an entity changes, so the results can be returned quickly when the application makes a query. Datastore mode provides built-in indexes automatically, but needs to know in advance which composite indexes the application will require. You specify which composite indexes your application needs in a configuration file.

  4. umax commented on Feb 3, 2021

    @umax
    Author

    @tseaver does provided composite indexes is not enough for my query?

  5. tseaver commented on Feb 3, 2021

    @tseaver
    Contributor

    @umax Firestore doesn't auto-provide composite indexes: it only has indexes on individual fields. You have to define composite indexes manually.

  6. umax commented on Feb 3, 2021

    @umax
    Author

    @tseaver in the description of this issue I provided list of composite indexes from index.yaml file. Without these indexes the query does not work at all.

  7. BinarSkugga commented on Feb 12, 2021

    @BinarSkugga

    Possibly related to #145

  8. umax commented on Feb 15, 2021

    @umax
    Author

    What I did: I created composite index and use projection field to fetch only custom fields of entity. But this not solve problem in general. I think that 7-8 seconds to fetch 1500 is not acceptable for official library for Google services.

  9. tseaver commented on Mar 23, 2021

    @tseaver
    Contributor

    @umax I'm sorry I missed seeing the index definition in your initial description.

    I wonder if the second index (the "descending" one) is causing the back-end to choke?

  10. tsteinruecken commented on Mar 24, 2021

    @tsteinruecken

    Hi,

    I guess we’ve ran into the same issue (tested on 2.1.0 and several older versions). We have a query that returns 30 entities (no filter, no order). The combined size of them is less than 200kb. Fetching them from an Appengine F2 instance takes close to 0.8 Seconds. To debug this I’ve split the fetch by running the query keys-only (which is fast!) and then calling get_multi separately. As far as i can tell, the time is wasted in client.py:547. Copying these 30 protobufs into entities takes 0.6 seconds of said 0.8 seconds total. I’ve also iterated the list of these protobufs before and had each PB cast to string to ensure there’s no RPC in flight that's being waited on inside entity_from_protobuf. For me it seems to be entirely CPU-Hog there. Our entities contain several lists and nested entities, maybe this is contributing to this slowdown as i can’t see anything obviously wrong with that entity_from_protobuf function?

  11. craiglabenz commented on Mar 29, 2021

    @craiglabenz
    Contributor

    Relatedly, I've been exploring some query slowness here. I'm going to add @tsteinruecken's findings to my search for the culprit.

  12. tseaver commented on Apr 14, 2021

    @tseaver
    Contributor

    I have written a script to test google.cloud.datastore.helpers.entity_from_protobuf, which is the workhorse used in marshaling query results into Entity objects.

    $ python3.8 -m venv /tmp/datastore-1.15.3
    
    $ /tmp/datastore-1.15.3/bin/pip install --upgrade setuptools pip wheel
    ...
    Successfully installed pip-21.0.1 setuptools-56.0.0 wheel-0.36.2
    
    $ /tmp/datastore-1.15.3/bin/pip install "google.cloud-datastore==1.15.3"
    ...
    Successfully installed cachetools-4.2.1 certifi-2020.12.5 chardet-4.0.0 google-api-core-1.26.3 google-auth-1.28.1 google-cloud-core-1.6.0 google.cloud-datastore googleapis-common-protos-1.53.0 grpcio-1.37.0 idna-2.10 packaging-20.9 protobuf-3.15.8 pyasn1-0.4.8 pyasn1-modules-0.2.8 pyparsing-2.4.7 pytz-2021.1 requests-2.25.1 rsa-4.7.2 six-1.15.0 urllib3-1.26.4
    
    $ python3.8 -m venv /tmp/datastore-2.1.0
    
    $ /tmp/datastore-2.1.0/bin/pip install --upgrade setuptools pip wheel
    ...
    Successfully installed pip-21.0.1 setuptools-56.0.0 wheel-0.36.2
    
    $ /tmp/datastore-2.1.0/bin/pip install "google-cloud-datastore==2.1.0"
    ...
    Successfully installed cachetools-4.2.1 certifi-2020.12.5 chardet-4.0.0 google-api-core-1.26.3 google-auth-1.28.1 google-cloud-core-1.6.0 google-cloud-datastore-2.1.0 googleapis-common-protos-1.53.0 grpcio-1.37.0 idna-2.10 libcst-0.3.18 mypy-extensions-0.4.3 packaging-20.9 proto-plus-1.18.1 protobuf-3.15.8 pyasn1-0.4.8 pyasn1-modules-0.2.8 pyparsing-2.4.7 pytz-2021.1 pyyaml-5.4.1 requests-2.25.1 rsa-4.7.2 six-1.15.0 typing-extensions-3.7.4.3 typing-inspect-0.6.0 urllib3-1.26.4
    
    $ /tmp/datastore-1.15.3/bin/python compare_perf_issue_1_15_3.py 
    Time: 1.3033227920532227
    
    $ /tmp/datastore-2.1.0/bin/python compare_perf_issue_1_15_3.py 
    Time: 13.733032941818237

    Those times are pretty repeatable.

  13. added a commit that references this issue on Apr 20, 2021
    5b67daa
  14. tseaver commented on Apr 20, 2021

    @tseaver
    Contributor

    Note that the merge of @craiglabenz's PR #155 improves the time for Datastore 2.x on my benchmark, from being a full 10x slower than Datastore 1.15.3 to about 3x slower.

  15. tsteinruecken commented on May 4, 2021

    @tsteinruecken

    @tseaver could you please reopen this issue? I don't consider it resolved at all.
    I've attached a sample appengine application. It contains a large entity to test.
    Deploy it, call /initDB first (it will write the contained entity 30 times into "test_kind").
    Then call /testFetch or /testBaseline. The baseline is what i consider should be the time it should take to fetch these entities (it does a roundtrip to the datastore keys-only, then deserializes the locally stored entity for each key received). It's about ~1.3 seconds on the configured F2 instance. Python-datastore==1.15.3 is already 5(!) times slower. 2.1.0 is fiveteen times slower than the baseline, and while there's a small improvement on 2.1.2 it's still fourteen times slower than given baseline (that's ~15 Seconds to fetch these 30 entities).
    appengine-datastore-bench.zip

  16. tseaver commented on May 4, 2021

    @tseaver
    Contributor
  17. reopened this on May 4, 2021
  18. added a commit that references this issue on Jul 9, 2021
    9910960
  19. added a commit that references this issue on Jul 9, 2021
    d0481bf
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

api: datastoreIssues related to the googleapis/python-datastore API.priority: p2Moderately-important priority. Fix may not be included in next release.type: questionRequest for information or clarification. Not an issue.

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions