django queryset __in 引起的性能问题

无图无真相,先上图,这是读django queryset文档的时候,文档上的一段note

django queryset __in 引起的性能问题_第1张图片
图片.png

当时读完这句,就是觉得说在mysql上对于__in的使用,需要把__in中的条件拆分成两句写,也没特别在意,之后的代码也是常常这么写,没察觉什么不对劲,虽然我们也是用mysql

Model.objects.filter(xx__in=queryset)

近期有客户反映,某个功能反映有点慢,我试了试,一个查询20w行左右的sql需要大约5s,这确实太慢了,定位到这句查询语句后,查看对应的sql,发现用了子查询,难怪那么慢,想起文档上的那个note(上图),然后改成

Model.objects.filter(xx__in=list(queryset.values_list('id',flat=True)))

Oh,sql的执行时间在200ms左右,看来文档说的还是很有道理的。

PS:两种结果转化为sql对比

#Model.objects.filter(xx__in=queryset) 实际执行的sql是
select ... where id in (select id from ...)
#Model.objects.filter(xx__in=list(queryset.values_list('id',flat=True)))实际执行的sql是
select ... where id in (1,2,3)

你可能感兴趣的:(django queryset __in 引起的性能问题)