django增加数据库查询速度的多种办法
orm raw
使用orm .raw()方法可以通过原生语句查询数据库
orm select_related和prefetch_related
由于这个仍然是使用外键链接的,但是django使用这两个语句增加了外键查询的速度,简而言之就是通过改变迭代查询为链表查询,但是如果是使用链表查询的,我们也可以不使用外键的方法来进行数据库查询,就是我后面将会提到的原生语句查询。因为django的外键添加是非常容易出错的。
使用原生语句访问数据库的原因
很多人都说django orm原生语句查询性能并不如预期,查询了一下网上,orm查询慢的主要原因是因为他需要封装一次queryset,虽然在使用时候会比较方便,但是确实造成了查询速度慢的问题。这也就是为什么需要用原生语句访问数据库的原因
使用pymysql链接数据库
conn=pymysql.connect(host='localhost',user='用户名',password=‘密码',database='数据库名',charset='数据库编码格式')
cursor=conn.cursor(cursor=pymysql.cursors.DictCursor)
cursor.execute(原生mysql查询语句)
查询结果参数=cursor.fetchall()
可以将conn作为一个单例对象方便在整个项目中调用
配置可以使用字典类型
config = {
'host':'localhost',
'port':3306,
'user':'用户名',
'password':'密码',
'database':'数据库',
'charset':'编码格式',
'cursorclass':pymysql.cursors.DictCursor,
}
对象名=pymysql.connect(**config)

使用django自带的db接口
这个和pymysql其实差别不大
from django.db import connection
# 获取游标对象
cursor = connection.cursor()
# 拿到游标对象后执行sql语句
cursor.execute("select * from book")
# 获取所有的数据
rows = cursor.fetchall()
当然直接使用这个语句获取到的是一个元组,和我们所需要的结果不符合所以还是使用之前pymysql的比较好

数据库视图
创建一个视图
mysql> create view 视图名
-> as
-> select * from areas;(原生语句)
使用视图进行查询
select * from v1;查询视图所有的字段
视图的查询和普通的表查询没有区别

修改视图
create or replace view 视图名
as
原生sql语句
alter view 视图名
as
原生sql语句
不能修改(更新)的视图:
- 包含以下关键字:分组函数,distinct,having ,union ,union all
- 常量视图
- Select里面包含子查询
- Join
- From一个不能更新的视图
优劣
优:
- 重用sql
- 简化复杂的sql操作,不必知道他的查询细节
- 保护数据,提高安全性
劣:
4. 在数据库删改频率较快的情况下,视图无法及时更新
由于有这个比较致命的劣势,其实我是不怎么会用到视图的,数据库中不怎么变的表真的不多
数据库存储过程
创建数据库存储过程
DELIMETER $ 把数据结尾符号变成$ 这个是为了不在写原生语句结尾的分号时候直接跳出
CREATE PROCEDURE 存储过程名称(参数列表)
BEGIN
原生sql语句
END
调用存储过程
CALL
简单的一个例子

这是无参数的存储过程
查看创建的存储过程
show create procedure 存储过程名;

删除存储过程
drop procedure 存储过程名
参数模式
IN:该参数可以作为输入
OUT:该参数可以作为输出
INOUT:该参数可以作为输入也可以作为输出
in
mysql> create procedure hermit_areas(IN areas_name varchar(20))
-> BEGIN
-> select * from areas where name=areas_name;
-> END
-> $
call hermit_areas('凤川镇')$

注意参数名不要和列名重复
out
mysql> create procedure hermit_areas_id(IN areas_name varchar(20),OUT areas_id INT)
-> BEGIN
-> select id into areas_id from areas where name=areas_name;
-> END
-> $
call hermit_areas_id('凤川镇',@areas_id)$
select @areas_id$

inout
create procedure inout_show(INOUT a INT,INOUT b INT) BEGIN set a=a*a; set b=b*b; END$
set @x=10$
set @y=100$
call inout_show(@x,@y)$
select @x,@y$

创建一个链表查询的存储过程
由于很多时候我们的链表查询都是一对多的关系,我们很多时候都可以用左连接和右连接来实现我们的链表查询
使用图书馆id查看图书馆被浏览的时间
mysql> create procedure get_libraries_explore_time(IN libraryid INT)
-> BEGIN
-> select libraries.id,libraries_explore_time.explore_data_time from libraries left join libraries_explore_time on libraries.id=libraries_explore_time.library_id where libraries.id=libraryid;
-> END
-> $
call get_libraries_explore_time(12)$

这样的查询方式不仅增快了查询速度,而且复杂程度也并不高

本文介绍了多种提升Django数据库查询速度的方法,包括使用ORM的raw()、select_related和prefetch_related,阐述了使用原生SQL的原因,探讨了pymysql与Django内置db接口的使用,详细讲解了数据库视图的创建、查询和优缺点,并介绍了存储过程的创建、参数模式及其在链表查询中的应用。

4449

被折叠的 条评论
为什么被折叠?



