WebHU - Programozási kérdések és válaszok

Django Paginate CPU Időskálázás a kiválasztott objektumok számával, nem megjelenített objektumokkal

Van egy egyszerű adatbázisom körülbelül 3900 bejegyzéssel, és egy általános nézetet (django.views.generic.list_detail.object_list) használok a django-oldalszámozással (a paginate_by-n keresztül) az adatbázisban lévő adatok böngészéséhez, de néhány lekérdezés nagyon lassú. .

Az a furcsa, hogy annak ellenére, hogy oldalanként csak 50 objektumot mutat, a renderelési idő nagyjából lineárisan skálázódik a kiválasztott objektumok számával (és nem rendezem az objektumokat). Például, ha ~3900, ~1800, ~900, ~54 kiválasztott objektummal lekérdezek, akkor ~8500 ms, ~4000 ms, ~2500 ms, ~800 ms CPU-időt vesz igénybe (a django-debug-toolbar segítségével) míg az SQL csak ~50 ms, ~40 ms, ~35 ms, ~30 ms, míg az összes oldalon pontosan 50 objektum volt. A django optimalizálási oldalon<< a select_related használatával minimálisra csökkentettem az SQL-lekérdezések számát. /a>.

A profilozó köztes szoftverek használatával a hosszú lekérdezésekre fordított idő túlnyomó részét a db dolgok elvégzésével töltik:

         735924 function calls (702255 primitive calls) in 11.950 CPU seconds

   Ordered by: internal time, call count

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
35546/3976    4.118    0.000    9.585    0.002 /usr/local/lib/python2.6/dist-packages/django/db/models/query.py:1120(get_cached_row)
    30174    3.589    0.000    3.991    0.000 /usr/local/lib/python2.6/dist-packages/django/db/models/base.py:250(__init__)

 ---- By file ----

      tottime
47.0%   3.669 /usr/local/lib/python2.6/dist-packages/django/db/models/base.py
 7.7%   0.601 /usr/local/lib/python2.6/dist-packages/django/db/models/options.py
 6.8%   0.531 /usr/local/lib/python2.6/dist-packages/django/db/models/query_utils.py
 6.6%   0.519 /usr/local/lib/python2.6/dist-packages/django/db/backends/sqlite3/base.py
 6.4%   0.496 /usr/local/lib/python2.6/dist-packages/django/db/models/sql/compiler.py
 5.0%   0.387 /usr/local/lib/python2.6/dist-packages/django/db/models/fields/__init__.py
 3.1%   0.244 /usr/local/lib/python2.6/dist-packages/django/db/backends/util.py
 2.9%   0.225 /usr/local/lib/python2.6/dist-packages/django/db/backends/__init__.py
 2.7%   0.213 /usr/local/lib/python2.6/dist-packages/django/db/models/query.py
 2.2%   0.171 /usr/local/lib/python2.6/dist-packages/django/dispatch/dispatcher.py
 1.7%   0.136 /usr/local/lib/python2.6/dist-packages/django/template/__init__.py
 1.7%   0.131 /usr/local/lib/python2.6/dist-packages/django/utils/datastructures.py
 1.1%   0.088 /usr/lib/python2.6/posixpath.py
 0.8%   0.066 /usr/local/lib/python2.6/dist-packages/django/db/utils.py
...
 ---- By group ---

      tottime
89.5%   6.988 /usr/local/lib/python2.6/dist-packages/django/db
 3.6%   0.279 /usr/local/lib/python2.6/dist-packages/django/utils
...

Megértem, hogy az SQL-lekérdezés miért skálázható a kiválasztott bejegyzések számával. Nem értem azonban, hogy a CPU többi idejét miért kellene befolyásolni. Ez nagyon ellentmondásos, és azon tűnődtem, hogy van-e valami hibakeresési/profilozási tipp, amiben valaki tudna nekem segíteni.

A django-1.2.3 használata sqlite-tal, python2.6-tal, apache2-preforkkal (bár az mpm-workerre váltás nem változtatott lényegesen a dolgokon). Bármilyen tippet/trükköt nagyra értékelnénk. Úgy tűnik, hogy a memóriahasználat sem számít (2 Gb RAM van a gépben és az ingyenes azt mondja, hogy csak 300 Mb használatban van (ráadásul 600 Mb gyorsítótár)) és az adatbázis ugyanazon a szerveren van, mint a gép.

Megtaláltam a hibámat. Megtaláltam a hibámat. Ellenőriztem az eredeti lekérdezéskészlet hosszát, hogy 1-es hosszúságú-e (majd az object_detail elemre mentem, ha igen). Ez a teljes lekérdezéskészlet kiértékelését eredményezte (ami a django-debug-toolbar szerint még mindig csak 5 ms-ig tartott), de minden jelentősen lelassult.

Alapvetően volt valami hülyeség, mint pl.

    if len(queryset) == 1:                                 
        return HttpResponseRedirect( fwd to object_detail url ...)
    return object_list(request, queryset=queryset, paginate_by=  ...)

amely kiértékelte a teljes lekérdezést; nem a lapszámozott lekérdezés.


  • Vannak indexek beállítva az sqlite adatbázisban? Ellenkező esetben az sqlite lineáris keresést végezhet szűréshez vagy rendezéshez. 01.11.2010
  • Jelenleg nincs beállítva indexem; de én sem rendezem az eredményeket, és az a benyomásom, hogy a django-debug-toolbar megszorozza az SQL lekérdezéseket. Tehát ha az SQL lekérdezések összesen 50 ms-ot tesznek ki a ~3900 objektum közül 1-50, és ~30 ms a ~54 objektum közül 1-50 kiválasztásához, akkor a CPU-idő különbsége csak 20 ms legyen, nem a jelenlegi 7800 ms-os különbség. . 01.11.2010

Válaszok:


1

Amikor a django oldalszámozást végez, szabványos QuerySet szeletelést használ az eredmények eléréséhez, ez azt jelenti, hogy a LIMIT és OFFSET karaktereket használja.

Megtekintheti az ORM által generált SQL-t a str() meghívásával a QuerySet .query attribútumában:

    print MyModel.objects.all().query
    print MyModel.objects.all()[50:100].query

Ezután megkérheti az sqlite-ot, hogy EXPLAIN adja meg a lekérdezést, és megnézze, mit próbál tenni az adatbázis. Feltételezem, hogy olyan mezőre rendezel, aminek nincs indexe. A EXPLAIN QUERY PLAN megmondja, hogy milyen indexeket használtak volna a http://www.sqlite.org/lang_explain.html

01.11.2010
  • Ez hasznos volt, és végigvezetett a nyomon, hogy valóban végigolvassam az SQL-lekérdezéseket (a fenti szerkesztett kérdésben magyarázva). 01.11.2010
  • Ha további információra van szüksége a lekérdezés kiértékeléséről, lásd: docs.djangoproject.com/en/dev/ref/models/querysets/ Megpróbálhatja a Len() helyett a QuerySet...count() függvényt. 01.11.2010
  • Új anyagok

    A rádiógomb ellenőrzött eseményének használata a jQueryben
    Ebben a cikkben látni fogjuk, hogyan kell dolgozni a jquery választógombbal ellenőrzött eseményeivel. A választógombok HTML gombok, amelyek segítenek kiválasztani egyetlen értéket egy csoportból...

    Körkörös függőségek megoldása terraformban adatforrásokkal – lépésről lépésre
    Mi az a körkörös függőségek Dolgozzunk egy egyszerű eseten, amikor az SQS-sor és az S3-vödör közötti körkörös függőség problémája van egy egymástól függő címkeérték miatt. provider..

    Miért érdemes elkezdeni a kódolást 2023-ban?
    01100011 01101111 01100100 01100101 — beep boop beep boop Világunk folyamatosan fejlődik a technológia körül, és naponta fejlesztenek új technológiákat a valós problémák megoldására. Amint..

    🎙 Random Noise #2  – Örökbefogadás és hit
    az analitika íratlan világának gondozása Szeretné, hogy ezek a frissítések a postaládájába kerüljenek? Iratkozzon fel itt . "Ha önvezető autókat gyártanak, akkor mi miért ne..

    A legrosszabb politika és prediktív modellek májátültetésre jelöltek számára az Egyesült Államokban
    A máj (vagy óangolul lifer) az emberi test legnehezebb belső szervére utal, amely csendesen működik a nap 24 órájában. Mit csinál a máj? 500 feladatot hajt végre a szervezet egészségének..

    5 webhely, amely 2022-ben fejleszti front-end fejlesztői készségeit
    Frontendmentor.io A tényleges projektek létrehozásával a Frontendmentor.io segítséget nyújt a front-end kódolási képességeinek fejlesztésében. A kódolást azután kezdheti meg, hogy..

    Mikor kell használni a Type-t az interfészhez képest a TypeScriptben?
    A TypeScript a JavaScript gépelt szuperkészlete, amely statikus gépelést ad a nyelvhez. Ez megkönnyíti a robusztus és karbantartható kód írását azáltal, hogy a hibákat a fordítási időben..