Django开发过程中【数据库的优化】【提升性能(高并发))】【代码优化】(面试可能用到)

1.Django开发过程中数据库的优化

     禁止使用外键,如果有外键完整性约束,需要应用程序控制
解读:外键会导致表与表之间耦合,update与delete操作都会涉及相关联的表,十分影响sql 的性能,甚至会造成死锁。高并发情况下容易造成数据库性能,大数据高并发业务场景数据库使用以性能优先。
关于如何体现表与表之间的关联性和如何维护数据完整性和一致性:

1.关联性:那就是设计数据库的时候,要让所有人知道表与表之间的通过那个字段关联起来,所以字段名称命名上会做一些文章。

2. 如何维护数据完整性和一致性:通过外部程序的力量,启用事务的方式,比如:
START TRANSACTION;
UPDATE A SET co1=** …;
UPDATE B SET A_co1=**…;
COMMIT;
注释:假设场景 A表的col1变成某值之后,B表中的A_col1字段也必须修改为对应的值`…
  • 2.使用缓存,减少对数据库的访问。
  • 3.在ORM框架下设置表时,能用varchar确定字段长度时,就不用text;
  • 4.可以给搜索频率高的字段属性,在定义时创建索引。
    如果对多个字段创建索引以后,注意查询的顺序遵循最左前缀原则。即创建的顺序是name,age,country,查询时可以是只查name,或者只查name,age,或者按顺序查找name,age,country,否则其他顺序都将进行全表扫描。
  • 5.Django ORM框架下的Queryset本来就是有缓存的。
  • 6.如果一个页面需要多次连接数据库,最好一次性取出所有数据,减少对数据库的查询次数。
  • 7.若页面只需要数据库里一两个字段时,可以用Queryset.values()
  • 8.在模板标签里使用with标签可以缓存Queryset的查询结果。
  • 9.对于多张表联合查询的,查询频率较高的字段可以在其关联的另一张表设置冗余字段,例如sales销量、评论量、默认图片地址default_img_url等,以空间换时间。根据具体项目权衡。

2.django开发 如何提升性能(高并发)?

从三个方面进行优化:web前端性能优化,web服务器端的性能优化,运维部署的优化。

2.1web前端优化

  • 1.减少http请求,减少数据库的访问量,比如使用雪碧图。
    【雪碧图是根据CSS sprite音译过来的,就是将很多很多的小图标放在一张图片上,就称之为雪碧图。
    使用雪碧图的目的:
    有时为了美观,我们会使用一张图片来代替一些小图标,但是一个网页可能有很多很多的小图标,浏览器在显示页面的时候,就需要像服务器发送很多次访问请求,这样一来,一是造成资源浪费,二是会导致访问速度变慢。这时候,把很多小图片(需要使用的小图标)放在一张图片上,按照一定的距离隔开,就解决了上述的两个问题。】
  • 2 .使用浏览器缓存,将一些常用的css/js/logo图标这些静态资源缓存到本地浏览器,通过设置http头中的cache-control 和expires属性,可设定浏览器缓存,缓存时间可以自定义。
  • 对html、css、js文件进行压缩,减少网络通信量。

2.2 web后端优化

  • 1.使用合理的缓存技术,对一些常用到的动态数据,比如首页做一个缓存,或者某些常用的数据做缓存,设置一定的过期时间,这样减少了数据库的压力,提升网站性能。
  • 2.使用celery消息队列,将耗时的操作丢到队列里,让worker去监听队列的任务,实现异步操作,比如发短信、发邮件。
  • 3.代码上的优化,避免写冗余代码。
  • 4.数据库查询语句的优化,对于建了索引的字段查询时遵循最左原则,避免出现全表扫描。

2.3.运维部署优化

  • 1.搭建nginx服务器,搭建服务器集群,充分利用nginx服务器的负载均衡和反向代理功能。
  • 2.数据库设置读写分离,可对读的那台数据库使用myisam引擎。写的那台使用innodb引擎。

3.代码优化从哪些方面考虑?有什么想法?

3.1 优化算法时间

算法的时间复杂度对程序的执行效率影响最大,在python中选择合适的数据结构来优化时间复杂度。例如list和set查找一个元素的时间复杂度分别是O(n)和O(1).不同场景不同的优化方式。总得来说,一般有分治,分支界限,贪心,动态规划等思想。

3.2 循环优化

减少python在循环内部的执行的工作量.例如列表推导式和字典推导式。

3.3 并行编程

多进程:对于CPU 密集型的程序,可以使用multiprocessing 的Process,Pool 等封装好的类,通过多进程的方式实现并行计算。
多线程:对于IO 密集型的程序,multiprocessing.dummy 模块使用multiprocessing 的接口封装threading,使得多线程编程也变得非常轻松(比如可以使用Pool 的map 接口,简洁高效)。
布式:multiprocessing 中的Managers 类提供了可以在不同进程之共享数据的方式,可以在此基础上开发出分布式的程序。

3.4 使用性能分析工具

除了上面在ipython 使用到的timeit 模块,还有cProfile。cProfile 的使用方式也非常简单:python-mcProfilefilename.pyfilename.py 是要运行程序的文件名,可以在标准输出中看到每一个函数被调用的次数和运行的时间,从而找到程序的性能瓶颈,然后可以有针对性地优化。

3.5 合理使用copy与deepcopy

对于dict和list等数据结构的对象,直接赋值使用的是引用的方式。而有些情况下需要复制整个对象,这时可以使用copy包里的copy和deepcopy,这两个函数的不同之处在于后者是递归复制的。效率也不一样。(以下程序在ipython中运行)

    import copy
    a = range(100000)
    %timeit -n 10 copy.copy(a)     # 运行10次 copy.copy(a)
    %timeit -n 10 copy.deepcopy(a)
    10 loops, best of 3: 1.55 ms per loop
    10 loops, best of 3: 151 ms per loop

timeit后面的-n表示运行的次数,后两行对应的是两个timeit的输出,下同。由此可见后者慢一个数量级。

3.6使用dict或set查找元素

python dict和set都是使用hash表来实现(类似c++11标准库中unordered_map),查找元素的时间复杂度是O(1)

3.7 合理使用生成器(generator)和yield

3.8 不借助中间变量交换两个变量的值(a,b=b,a)

3.9 终级大杀器:PyPy

PyPy是用RPython(CPython的子集)实现的Python,根据官网的基准测试数据,它比CPython实现的Python要快6倍以上。快的原因是使用了Just-in-Time(JIT)编译器,即动态编译器,与静态编译器(如gcc,javac等)不同,它是利用程序运行的过程的数据进行优化。由于历史原因,目前pypy中还保留着GIL,不过正在进行的STM项目试图将PyPy变成没有GIL的Python。

如果python程序中含有C扩展(非cffi的方式),JIT的优化效果会大打折扣,甚至比CPython慢(比Numpy)。所以在PyPy中最好用纯Python或使用cffi扩展。

随着STM,Numpy等项目的完善,相信PyPy将会替代CPython。

3.10 使用性能分析工具

除了上面在ipython使用到的timeit模块,还有cProfile。cProfile的使用方式也非常简单: python -m cProfile filename.py,filename.py 是要运行程序的文件名,可以在标准输出中看到每一个函数被调用的次数和运行的时间,从而找到程序的性能瓶颈,然后可以有针对性地优化。

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值