celery是基于python实现的一个异步任务的调度工具,同时还是一个任务队列,主要用于处理耗时的任务:
celery主要由三部分组成:
一般使用在比较耗时的场景中;比如:发送短信和邮箱的验证还有我们django中详情页面的静态化
物理硬件方面:要公司前期投入
SQL优化
1. 对经常使用的字段建立索引
2. 对于查询的数据建立缓存, 例如把省市区的信息缓存,
3. 对于等价的谓词: 把原来的between and 更改为 <=
4. 在where语句里面,尽量少使用外连接,尽可能使用内链接。
SQL优化一般理解是让SQL运行更快。实现MySQL优化可以从下面这些角度实现:
1. 在查询频率高的字段建立索引和缓存,对于经常查询的数据建立索引会提升查询速度,同时把经常用的数据进行缓存,避免对数据库的多次查询减少磁盘的IO,节约时间。
2. 在where查询子语句上尽量避免对字段的NULL值判断,否则数据库引擎将会放弃索引而使用全表扫描. 如: select id from t where num is null 可以在num上设置默认值0,确保表中num列没有null值,然后这样查询:select id from t where num=0
3.应尽量避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描。
4.应尽量避免在 where 子句中使用 or 来连接条件,否则将导致引擎放弃使用索引而进行全表扫描,如:
select id from t where num=10 or num=20
可以这样查询:
select id from t where num=10
union all
select id from t where num=20
5.in 和 not in 也要慎用,否则会导致全表扫描,如:
select id from t where num in(1,2,3)
对于连续的数值,能用 between 就不要用 in 了:
select id from t where num between 1 and 3
6.下面的查询也将导致全表扫描:
select id from t where name like '%abc%'
7.应尽量避免在 where 子句中对字段进行表达式操作,这将导致引擎放弃使用索引而进行全表扫描。如:
select id from t where num/2=100
应改为:
select id from t where num=100*2
8.应尽量避免在where子句中对字段进行函数操作,这将导致引擎放弃使用索引而进行全表扫描。如:
select id from t where substring(name,1,3)='abc'--name以abc开头的id
应改为:
select id from t where name like 'abc%'
9.不要在 where 子句中的“=”左边进行函数、算术运算或其他表达式运算,否则系统将可能无法正确使用索引。
10.在使用索引字段作为条件时,如果该索引是复合索引,那么必须使用到该索引中的第一个字段作为条件时才能保证系统使用该索引,
否则该索引将不会被使用,并且应尽可能的让字段顺序与索引顺序相一致。
11.不要写一些没有意义的查询,如需要生成一个空表结构:
select col1,col2 into #t from t where 1=0
这类代码不会返回任何结果集,但是会消耗系统资源的,应改成这样:
create table #t(...)
12.很多时候用 exists 代替 in 是一个好的选择:
select num from a where num in(select num from b)
用下面的语句替换:
select num from a where exists(select 1 from b where num=a.num)
13.并不是所有索引对查询都有效,SQL是根据表中数据来进行查询优化的,当索引列有大量数据重复时,SQL查询可能不会去利用索引,
如一表中有字段sex,male、female几乎各一半,那么即使在sex上建了索引也对查询效率起不了作用。
14.索引并不是越多越好,索引固然可以提高相应的 select 的效率,但同时也降低了 insert 及 update 的效率,因为 insert 或 update 时有可能会重建索引,所以怎样建索引需要慎重考虑,视具体情况而定。一个表的索引数最好不要超过6个,若太多则应考虑一些不常使用到的列上建的索引是否有必要。
15.尽量使用数字型字段,若只含数值信息的字段尽量不要设计为字符型,这会降低查询和连接的性能,并会增加存储开销。
这是因为引擎在处理查询和连接时会逐个比较字符串中每一个字符,而对于数字型而言只需要比较一次就够了。
16.尽可能的使用 varchar 代替 char ,因为首先变长字段存储空间小,可以节省存储空间, 其次对于查询来说,在一个相对较小的字段内搜索效率显然要高些。
17.任何地方都不要使用 select * from t ,用具体的字段列表代替“*”,不要返回用不到的任何字段。
18.避免频繁创建和删除临时表,以减少系统表资源的消耗。
19.临时表并不是不可使用,适当地使用它们可以使某些例程更有效,例如,当需要重复引用大型表或常用表中的某个数据集时。但是,对于一次性事件,最好使用导出表。
20.在新建临时表时,如果一次性插入数据量很大,那么可以使用 select into 代替 create table,避免造成大量 log ,
以提高速度;如果数据量不大,为了缓和系统表的资源,应先create table,然后insert。
21.如果使用到了临时表,在存储过程的最后务必将所有的临时表显式删除,先 truncate table ,然后 drop table ,这样可以避免系统表的较长时间锁定。
22.尽量避免使用游标,因为游标的效率较差,如果游标操作的数据超过1万行,那么就应该考虑改写。
23.使用基于游标的方法或临时表方法之前,应先寻找基于集的解决方案来解决问题,基于集的方法通常更有效。
24.与临时表一样,游标并不是不可使用。对小型数据集使用 FAST_FORWARD 游标通常要优于其他逐行处理方法,尤其是在必须引用几个表才能获得所需的数据时。
在结果集中包括“合计”的例程通常要比使用游标执行的速度快。如果开发时间允许,基于游标的方法和基于集的方法都可以尝试一下,看哪一种方法的效果更好。
25.尽量避免大事务操作,提高系统并发能力。26.尽量避免向客户端返回大数据量,若数据量过大,应该考虑相应需求是否合理。
其他的SQL优化参考:
1. https://blog.csdn.net/z719725611/article/details/52922695
2. https://blog.csdn.net/heqinghua217/article/details/78600967
3. https://blog.csdn.net/wwzuizz/article/details/54602058
4. https://www.cnblogs.com/easypass/archive/2010/12/08/1900127.html
持久化: 把数据存放到断电也不会丢失的设备中,例如: 文件, mysql
快照(RDB),是redis默认做持久化的方式
实现原理:
redis是由C语言实现的,fork函数,会把主进程复制一个子进程, 子进程会把内存的数据依次遍历出来,存放到配置指定的二进制文件dump.rdb中。
实现快照:
只要更改配置文件,默认提供额三种级别的快照形式
[外链图片转存失败(img-ed1txc6p-1563958105617)(C:\Users\zyw\AppData\Local\Temp\1538014151203.png)]
优点:
缺点:
断电容易造成数据丢失,断电的时间段内的数据不能备份
AOF(Append only file) , 以日志文件追加的方式实现的
实现原理:
把所有内存中数据以writer追加的方法写道日志文件中。
实现:
修改配置文件,
[外链图片转存失败(img-4qCwKrNS-1563958105618)(C:\Users\zyw\AppData\Local\Temp\1538015831088.png)]
优点:
缺点:
RDB快照
redis是默认做数据持久化的,默认的方式是快照(snapshotting),把内存的数据写入本地的二进制文件dump.rdb文件中。
快照持久化实现原理:
Redis借助了fork命令的copy on write机制。在生成快照时,将当前进程fork出一个子进程,然后在子进程中循环所有的数据,将数据写成为RDB文件,使用redis的save命令调用这个过程。
快照的配置有下面三个级别,配置是在redis的配置文件中。
RDB快照持久化的优点:
RDB快照持久化的缺点:
一旦数据库出现问题,那么我们的RDB文件中保存的数据并不是全新的,从上次RDB文件生成到Redis停机这段时间的数据全部丢掉了。
AOF
AOF日志的全称是append only file,从名字上我们就能看出来,它是一个追加写入的日志文件.
实现原理:
在使用aof时,redis会将每一个收到的写命令都通过write函数追加到文件中,当redis重启时会通过重新执行文件中保存的写命令来在内存中重建整个数据库的内容.Redis还能对AOF文件通过BGREWRITEAOF 重写,使得AOF文件的体积不至于过大.
由于AOF是把操作日志写入日志文件中,那么AOF的操作安全性如何保证?可以在配置文件中通过配置告诉redis我们想要使用fsync函数强制写入到磁盘的时间。
配置分为三种:
AOF的优点:
redis存储在内存中, mysql 存储在磁盘中。
redis存储的是key/value的键值对,查找的时间复杂度0(1), 常数级别
mysql 存储数据依靠数据引擎: Innodb, MyisAm. l两种引擎都是使用的B-TREE来进行数据的存放或查找
时间复杂度0(logn),对数级别。
mysql存储的时候,一般存放到表格中,开表格查询,通过外键或者内链接外连接;进行磁盘的读写,
redis查找数据,只要知道key,就可以直接拿到对应的值
redis,是单线程进行多路io服用, 单线程就可以比卖你多线程的创建的时间开销; 多路io复用可以共享数据;
对于多核的电脑操作redis,把数据进行分区。
特点:
快: C语言实现的,把数据都存储在内存中,在内存中存储时是以key/value
数据类型多:string, List, Set, Zset, Hash
数据的持久化:
持久化: 把存储在内存中的数据,写入本地的文件中
在redis中默认使用快照(RDB)模式进行数据持久化, 以二进制形式写入本地的dump.rdb
做主从复制: 在主服务器上只进行写的操作,而在从的服务器上进行读的操作
分布式及高可用
高可用: 使用Redis自带的哨兵机制
能支持事务,发布/订阅模式
存储数据
import redis
conn = redis.StricRedis('127.0.0.1', 6379)
conn.lset('key', 'name')
conn.lrange('key', 0 , -1)
设置长连接
修改配置文件redis.conf
tcp-keepalive = 0 # 默认禁用长连接
tcp-keepalive = 1 # 启动长连接
长连接的概念:
在一个tcp连接时,连接后发送数据,数据发送完成后并不会断开连接,客户端和服务端会发送测试数据来保持连接
短链接概念:在一个tcp连接中,数据发送完成就断开连接, 如果再有数据要发送,就重新建立连接。
长连接的好处: 节约时间