首页 > 解决方案 > Django注解优化

问题描述

我们应用 django 注解创建一个 postrgesql 数据库查询,注解 33 列,其中 16 列是来自相关 table_1 的普通值和 16 计算基于 table_1 中的相同值和 table_1 中的另一个值一一划分。

一点澄清: 1.有两个表:table_0 中的 table_0 和 table_1 column_n 与 table_1 具有 ManyToMany 关系 2.从 table_0 中查询值 3.从 table_1 中注释值,遵循类似的方式:

def get_annotation_values(key, expression_):
    return {
        key: Subquery(
        expression_.values('value')[:1]
        ),
    }

def get_annotation_expression(key, v):
    return {
        key:(Case(
            When(param_0_0=0, then=None),
            default=ExpressionWrapper( (Round( (Cast('param_0_0', FloatField())-Cast(          'param_'+str(v), FloatField() ) )/Cast('param_0_0', FloatField() )*Decimal(100))),
                                       output_field=FloatField()
                                      ),    
                                      output_field = IntegerField(),
                )
           ),
        }


def get_default_table_object():
    timeintervals_hours = [30, 60, 90, 120, 3*60, 4*60, 5*60, 6*60, 24*60, 24*2*60, 24*3*60, 24*4*60, 24*5*60, 24*7*60, 24*10*60, 24*15*60]
    now = timezone.now()
    objects_ = table_0.objects.all()

    upper_interval = now + timedelta(hours=24)
    lower_interval = now - timedelta(hours=24)
    
    param_h = table_1.objects.all().filter(table_0=OuterRef('pk')).order_by('-updated_timestamp')
    objects_ = objects_.annotate(**get_annotation_values('param_0_0', param_h))

    for v in timeintervals_hours:
        upper_interval = now - timedelta(minutes=v) + timedelta(minutes=15)
        lower_interval = now - timedelta(minutes=v) - timedelta(minutes=15)
    
        param_h = table_1.objects.all().filter(table_0=OuterRef('pk'),      updated_timestamp__range=(lower_interval, upper_interval)).order_by('-updated_timestamp')
        objects_ = objects_.annotate(**get_annotation_values('param_'+str(v), param_h))
        objects_ = objects_.annotate( **get_annotation_expression('param_p_'+str(v), str(v)))
    return(objects_)

table_1.values 是 BigIntegerField 字段

那么,主要问题是可以使用任何 sql 方法对此类查询进行优化,或者可能替换它吗?

实际上,我们意识到可以只向 table_0 添加 16 或 32 个附加列,避免将 table_1 用作 ManyToMany 列。但是这样的决定是不可扩展的......

PS 创建所有需要的索引。PPS memcached 是一种选择,但我们猜测,它可以与任何 sql 技术结合使用。

标签: postgresqldjango-models

解决方案


推荐阅读