2
votes

Django - Requêtes SQL brutes ou ORM Django QuerySet

Je sais que Django Object Relational Mapper (ORM) aide à combler le fossé entre la base de données et notre code Exécution de requêtes brutes.

Mais je veux savoir ce qui est le meilleur: les requêtes SQL brutes ou Django QuerySet ORM.

Donc, pour cela, j'ai interrogé sur User Table -

print(orm_query.query)
SELECT `auth_user`.`id`, `auth_user`.`password`, `auth_user`.`last_login`, `auth_user`.`is_superuser`, `auth_user`.`username`, `auth_user`.`first_name`, `auth_user`.`last_name`, `auth_user`.`email`, `auth_user`.`is_staff`, `auth_user`.`is_active`, `auth_user`.`date_joined` FROM `auth_user`

print(raw_query.query)
select * from auth_user

Ensuite, j'ai interrogé Django ORM QuerySet -

raw_query = User.objects.raw("select * from auth_user")
raw_query
<RawQuerySet: select * from auth_user>

Après QuerySet, j'utilise raw -

orm_query = User.objects.all()
orm_query
<QuerySet [<User: superadmin>]>

Et puis j'ai essayé d'imprimer ces requêtes en utilisant .query et sa sortie -

from django.contrib.auth.models import User

Et j'ai trouvé orm_query beaucoup plus long que raw_query . Je veux savoir quelle est la meilleure requête raw ou orm . Que dois-je utiliser pour de meilleures performances. Quelle est la différence entre eux.


3 commentaires

En termes de vitesse de développement, l'utilisation de Django ORM intégré vous fera gagner manière plus de temps.


@DanielH. Vous voulez dire que pour la vitesse de développement, utilisez django orm et pour les performances raw fonctionnera mieux que queryset


Voir ma réponse pour plus de détails


3 Réponses :


3
votes

La requête générée par l'ORM de Django sélectionne chaque colonne explicitement, tandis que votre requête brute sélectionne toutes les colonnes avec le * . Le résultat doit être le même dans les deux cas, vous pouvez rester sans aucun problème avec la requête de l'ORM. Si vous souhaitez omettre certaines colonnes du résultat, vous pouvez toujours utiliser les méthodes queryset uniquement () et defer () ce qui réduira la charge utile renvoyée par la base de données ainsi que le travail nécessaire pour convertir les données brutes en objets python.

Il est fort probable que vous n'ayez besoin que de revenir aux requêtes SQL brutes pour résoudre des cas d'utilisation dont l'ORM de Django n'est pas capable. Dans la plupart des cas, les plus grands impacts sur les performances seront causés par le fait de ne pas accéder aux objets associés de la bonne manière (voir select_related () et prefetch_related () pour plus d'informations à ce sujet) ou ne pas utiliser indexe correctement. Consultez également la documentation de Django sur l ' optimisation de l'accès aux bases de données .


1 commentaires

Merci pour votre excellente explication. Je l'ai compris et j'espère que tout le monde aura cette question et réponse utiles.



2
votes

La longueur du texte SQL n'a pas d'importance, si vous voulez comparer les performances, vous devez utiliser quelque chose comme EXPLAIN ANALYZE (exemple pour les postgres), lisez les réponses pour le mysql

dev=> EXPLAIN ANALYZE SELECT
    auth_user.id,
    auth_user.password,
    auth_user.last_login,
    auth_user.is_superuser,
    auth_user.username,
    auth_user.first_name,
    auth_user.last_name,
    auth_user.email,
    auth_user.is_staff,
    auth_user.is_active,
    auth_user.date_joined 
FROM auth_user;
                                               QUERY PLAN                                               
--------------------------------------------------------------------------------------------------------
 Seq Scan on auth_user  (cost=0.00..10.50 rows=50 width=1527) (actual time=0.004..0.004 rows=0 loops=1)
 Planning time: 0.124 ms
 Execution time: 0.032 ms
(3 rows)

dev=> EXPLAIN ANALYZE select * from auth_user;
                                               QUERY PLAN                                               
--------------------------------------------------------------------------------------------------------
 Seq Scan on auth_user  (cost=0.00..10.50 rows=50 width=1527) (actual time=0.004..0.004 rows=0 loops=1)
 Planning time: 0.114 ms
 Execution time: 0.032 ms
(3 rows)

comme vous pouvez le voir le temps d'exécution est égal.


1 commentaires

Merci pour votre excellente explication. Je l'ai compris et j'espère que tout le monde aura cette question et réponse utiles.



1
votes

En général, Django ORM est assez bon pour faire ce dont vous avez généralement besoin pour les requêtes de base de données. Cela devient plus facile et particulièrement utile pour les requêtes complexes. Écrire des requêtes brutes pour ces cas peut devenir très fastidieux et prendre du temps. C'est pourquoi le temps de développement peut devenir un problème. Dans la plupart des cas, l'ORM sera tout aussi rapide que les requêtes SQL brutes. L'ORM devrait donc être votre choix par défaut.

Dans les quelques cas où les performances peuvent devenir un problème, suivez les recommandations de La réponse de Bernhard Vallant devrait être la première chose que vous essayez; select_related , prefecth_related , index de base de données, etc.


0 commentaires