Django query the database performance optimization

Now there is a user information data table, the table below the 10 user's name, nickname, age, work, etc.,

models file

from django.db import models
    
    class Job(models.Model):
        title=models.CharField(max_length=32)
    
    class UserInfo(models.Model):
        username=models.CharField(max_length=32)
        nickname=models.CharField(max_length=32)
        job=models.ForeignKey(to="Job",to_field="id",null=True)

  Data recorded in the table

 

   Additionally a table recorded in the worksheet user, the user's work related fields

 

   To identify each user's user name, nickname, and job information

index DEF (Request): 
        user_list = models.UserInfo.objects.all () 
    
        Print (user_list.query) # use when printing query 
        # print query result of print (type (user_list)) data type 
    
        for the User in user_list: 
    
            Print ( "% S -> S% -> S%"% (user.username, user.nickname, user.job.title)) 
    
        return the render (Request, 'index.html')

  Print information

SELECT "app01_userinfo"."id", "app01_userinfo"."username", "app01_userinfo"."nickname", "app01_userinfo"."job_id" FROM "app01_userinfo"
<class 'django.db.models.query.QuerySet'>
user1-->user1-->python
user2-->user2-->linux
user3-->user3-->golang
user4-->user4-->python
user5-->user5-->linux
user6-->user6-->golang
user7-->user7-->python
user8-->user8-->linux
user9-->user9-->golang
user10-->user10-->linux

  These operations are carried out in the service side, the performance of these queries is very low, traverse out important information 10 user's name, nickname, and other work to be performed 11 times in the two query the database, only the first user table identify all user records, you need to perform a query, the query job data tables, each cycle a list of user information, you need to query a working user information from the job table, the data table recorded a total of 10 user records, so it needs 10 cycles to complete the job information for all users from the job table queries, so a total of 11 times you need to perform database query operations, then there is what there are better ways to improve the efficiency of database queries?

index DEF (Request): 
        user_list = models.UserInfo.objects.values ( "username", "the Nickname", "the Job") 
    
        Print (user_list.query) # use when printing query 
        print (type (user_list)) # print query result data type 
        Print ( "user_list:", user_list) 
    
        for User in user_list: 
    
            Print (User [ "username"], User [ "Nickname"], User [ "Job"]) 
    
        return the render (Request, 'index. html ')

  Run the program, print the background information on the server:

SELECT "app01_userinfo"."username", "app01_userinfo"."nickname", "app01_userinfo"."job_id" FROM "app01_userinfo"
<class 'django.db.models.query.QuerySet'>
user_list: <QuerySet [{'username': 'user1', 'nickname': 'user1', 'job': 1}, {'username': 'user2', 'nickname': 'user2', 'job': 2}, {'username': 'user3', 'nickname': 'user3', 'job': 3}, {'username': 'user4', 'nickname': 'user4', 'job': 1}, {'username': 'user5', 'nickname': 'user5', 'job': 2}, {'username': 'user6', 'nickname': 'user6', 'job': 3}, {'username': 'user7', 'nickname': 'user7', 'job': 1}, {'username': 'user8', 'nickname': 'user8', 'job': 2}, {'username': 'user9', 'nickname': 'user9', 'job': 3}, {'username': 'user10', 'nickname': 'user10', 'job': 2}]>
user1 user1 1
user2 user2 2
user3 user3 3
user4 user4 1
user5 user5 2
user6 user6 3
user7 user7 1
user8 user8 2
user9 user9 3
user10 user10 2

  You can see, user_list query is still a queryset, but this is really a collection of objects inside a dictionary, but this time the query is only performed twice a database query, in this way, you only need two queries can get want to the data to optimize the efficiency of the database query

 

Database optimization of Django select_related initiative even-table query

  In the above example, the time to a collection of objects, can only query the current data table, can not query the other data table? Of course not, here select_related also can use this method, when the first query, in all ( ) followed by a select_related be active even table query, when creating these two data tables, job in the user data table as a foreignkey exist, so after adding select_ not just to record user query the database, while also check the records job data in the table

index DEF (Request): 
        . user_list = models.UserInfo.objects.all () select_related ( "the Job") 
    
        Print (user_list.query) # use when printing query 
        print (type (user_list)) # print data query results type 
        Print ( "user_list:", user_list) 
    
        for User in user_list: 
    
            Print ( "% S -> S% -> S%"% (user.username, user.nickname, user.job.title)) 
    
        return the render (request, 'index.html')

  Server print results

SELECT "app01_userinfo"."id", "app01_userinfo"."username", "app01_userinfo"."nickname", "app01_userinfo"."job_id", "app01_job"."id", "app01_job"."title" FROM "app01_userinfo" LEFT OUTER JOIN "app01_job" ON ("app01_userinfo"."job_id" = "app01_job"."id")
<class 'django.db.models.query.QuerySet'>
user_list: <QuerySet [<UserInfo: UserInfo object>, <UserInfo: UserInfo object>, <UserInfo: UserInfo object>, <UserInfo: UserInfo object>, <UserInfo: UserInfo object>, <UserInfo: UserInfo object>, <UserInfo: UserInfo object>, <UserInfo: UserInfo object>, <UserInfo: UserInfo object>, <UserInfo: UserInfo object>]>
user1-->user1-->python
user2-->user2-->linux
user3-->user3-->golang
user4-->user4-->python
user5-->user5-->linux
user6-->user6-->golang
user7 -> user7 -> python 
user8 -> user8 -> linux 
user9 -> user9 -> golang 
user10 -> user10 -> Linux

  View print out the query, including:

"FROM "app01_userinfo" LEFT OUTER JOIN "app01_job" ON ("app01_userinfo"."job_id" = "app01_job"."id")"

  Used to do with queries, you need only one you can check all the data

  Similarly, if you want to continue to work with the table, such as addition of an external key field desc, just in the query to join the job desc table on it

 user_list=models.UserInfo.objects.all().select_related("job__desc")

  As a result put three tables linked do not even query the table, but we must make sure that the applied field is foreignkey, if you use similar models.userinfo.objects.all () statements query, do not do cross-table query, only some of the current query data table, otherwise the query performance will drop a lot, if you want to check the data in other tables to add select_related (foreignkey field names); If you want to get data from multiple foreignkey fields, you can use select_related (ForeignKey field 1, foreignkey field 2, ...) will be reduced even table query performance, select_related is used with active query table.

 

perfetch_related Django database to optimize the operation of the non-active contingency table query

perfetch_related method is non-active contingency table queries, do not be a lot of queries of a compromise

Modify the view function index

index DEF (Request): 
    
        . user_list = models.UserInfo.objects.all () prefetch_related ( "the Job") 
    
        Print (user_list.query) # use when printing query 
        print (type (user_list)) # print data query results type 
        Print ( "user_list:", user_list) 
    
        for User in user_list: 
    
            Print ( "% S -> S% -> S%"% (user.username, user.nickname, user.job.title)) 
    
        return the render (request, 'index.html')

  Back-end print the results:

SELECT "app01_userinfo"."id", "app01_userinfo"."username", "app01_userinfo"."nickname", "app01_userinfo"."job_id" FROM "app01_userinfo"
<class 'django.db.models.query.QuerySet'>
user_list: <QuerySet [<UserInfo: UserInfo object>, <UserInfo: UserInfo object>, <UserInfo: UserInfo object>, <UserInfo: UserInfo object>, <UserInfo: UserInfo object>, <UserInfo: UserInfo object>, <UserInfo: UserInfo object>, <UserInfo: UserInfo object>, <UserInfo: UserInfo object>, <UserInfo: UserInfo object>]>
user1-->user1-->python
user2-->user2-->linux
user3-->user3-->golang
user4-->user4-->python 
user10 -> user10 -> Linux
user8 -> user8 -> linux
user7 -> user7 -> python
user6 -> user6 -> golang
user5 -> user5 -> linux
user9 -> user9 -> golang

  The method of using perfetch_related uncrosslinked table query operation is performed twice, the user will check all the data in the table, all the user table all job_id check out, and performs deduplication operation; query result three kinds of work the user is performed next query job title field data table select statement, so that the query is executed twice the data table, adding a field in perfetch_related job1 method, a database query is performed twice;

 

Django database optimization only method of operation:

index DEF (Request): 
        . user_list = models.UserInfo.objects.all () only ( "username") 
    
        Print (user_list.query) # use when printing query 
        print (type (user_list)) # print data query results type 
        Print ( "user_list:", user_list) 
    
        for User in user_list: 
    
            Print ( "% S -> S%"% (user.username, user.nickname)) 
    
        return the render (Request, 'index.html')

  Spool server information

SELECT "app01_userinfo"."id", "app01_userinfo"."username" FROM "app01_userinfo"
<class 'django.db.models.query.QuerySet'>
user_list: <QuerySet [<UserInfo: UserInfo object>, <UserInfo: UserInfo object>, <UserInfo: UserInfo object>, <UserInfo: UserInfo object>, <UserInfo: UserInfo object>, <UserInfo: UserInfo object>, <UserInfo: UserInfo object>, <UserInfo: UserInfo object>, <UserInfo: UserInfo object>, <UserInfo: UserInfo object>]>
user1-->user1
user2-->user2
user3-->user3
user4-->user4
user5-->user5
user6-->user6
user7-->user7
user8-->user8
user9-->user9
user10-->user10

  When executing the query operation plus the only method that results or a collection of objects, but you can see from the print out of the query, the query is executed operation, only queries the user id field and the username field, and no query nickname field but in the back of the cycle, and can print the user's nickname information, why, because the request was executed operations of a query, thus informed that query using the only method, which only added to the query field method, at the back query field which is used, add only argument is to take only a field from the query results, and the other method is to defer to exclude a field from the query fired in.

 

Database optimization of Django defer method

Modify defer view function

index DEF (Request): 
    . user_list = models.UserInfo.objects.all () the defer ( "username") 

    Print (user_list.query) # use when printing query 
    print (type (user_list)) # print data query results type 
    Print ( "user_list:", user_list) 

    for User in user_list: 

        Print ( "% S"% user.nickname) 

    return the render (Request, 'index.html')

  Print server information

SELECT "app01_userinfo"."id", "app01_userinfo"."nickname", "app01_userinfo"."job_id" FROM "app01_userinfo"
<class 'django.db.models.query.QuerySet'>
user_list: <QuerySet [<UserInfo: UserInfo object>, <UserInfo: UserInfo object>, <UserInfo: UserInfo object>, <UserInfo: UserInfo object>, <UserInfo: UserInfo object>, <UserInfo: UserInfo object>, <UserInfo: UserInfo object>, <UserInfo: UserInfo object>, <UserInfo: UserInfo object>, <UserInfo: UserInfo object>]>
user1
user2
user3
user4
user5
user6
user7
user8
user9
user10

  You can know by query print after use defer method only queries the user id field operations and user nickname field from the database, and no query username field, which can also improve the performance of database queries Django

 

Guess you like

Origin www.cnblogs.com/panshao51km-cn/p/11563213.html