我会尽我所能解释我的问题。我遇到性能问题,我想知道是否有更好的方法来设置它。优化Django queryset调用,大列表?
我有一个数据库,大概有150年的年份数据。每行有大约10列。
我在每30年一次的范围内运行一次“模拟”(我们将每个30yr块称为“周期”)。所以,第一周期将是1-31年。第二周期将是2-32年。周期3,3-33年。明白了吗?
all_data = DataPoint.objects.all().yearly()
cycle_length = 30
previous_data_points = []
for data_point in all_data:
if len(previous_data_points) < cycle_length:
previous_data_points.append(data_point)
continue
simulation_cycles.append(Cycle(previous_data_points))
if len(previous_data_points) == cycle_length:
previous_data_points.pop(0)
previous_data_points.append(data_point)
所以,对于每一个30年的周期,我喂Cycle
功能的30项查询集来初始化数据。问题是,当我使用Django的connection.queries列出发生了什么事情时,它看起来正在做3000多个查询,并且需要10-12秒,这对于它正在做的事情来说相当长。
在connection.queries列表中,当我将它传递给Cycle时(每个使用“我认为是我的.yearly的WHERE EXTRACT(MONTH FROM”),我看到它正在做30个单独的调用(每个数据点为1) ()过滤器被调用,但它也在Cycle()中记录查询,它实际上按日期查找数据点。我的应用程序确实运行了3000个查询(使用db上的连接),还是我的DataPoint.objects.all().your()调用中的一个大查询,并且其他所有内容都在内存中?
我正在尝试要理解为什么这样慢的运行我假设,我创造了这个巨大的对象列表:120个“周期”,每个对象都有30个单独的“年”对象,这些对象拥有自己的数据(以及用于计算的数据)供以后使用。记忆中有那么多物体会伤害我,还是那个小土豆?
编辑:
class Cycle:
def __init__(self, data_points):
self.range_start = data_points[0].data_date
self.range_end = data_points[-1].data_date
self.start_CPI = data_points[0].cpi
self.years = relativedelta(self.range_end, self.range_start).years + 1
self.sim = []
for i in range (0, self.years):
data_point = data_points[i]
self.sim.append(Segment(
date=self.range_start + relativedelta(years=i),
start_CPI=self.start_CPI,
yearly_equities_growth=data_point.yearly_equities_growth,
cpi=data_point.cpi,
dividend=data_point.dividend,
s_and_p_composite=data_point.s_and_p_composite,
long_interest_rate=data_point.long_interest_rate
))
class Segment:
def __init__(self, date, start_CPI, yearly_equities_growth, cpi, dividend, s_and_p_composite, long_interest_rate):
self.start_CPI = D(start_CPI)
self.date = date
self.portfolio = {
"start": None,
"end": None,
"inflation_adjusted_start": None,
"inflation_adjusted_end": None,
"fees": None
}
self.spending = None
self.inflation_adjusted_spending = None
self.equities = {
"start": None,
"growth": None,
"val": None
}
self.bonds = {
"start": None,
"growth": None,
"val": None
}
self.gold = {
"start": None,
"growth": None,
"val": None
}
self.cash = {
"start": None,
"growth": None,
"val": None
}
self.dividends = {
"growth": None,
"val": None
}
self.fees = None
self.yearly_equities_growth = D(yearly_equities_growth)
self.cumulative_inflation = 1 + (D(cpi) - self.start_CPI)/self.start_CPI
self.sum_of_adjustments = None
self.cpi = cpi
self.dividend = dividend
self.s_and_p_composite = s_and_p_composite
self.long_interest_rate = long_interest_rate
你可以分享Cycle类的代码吗?更好地了解你的问题 – jperelli
完成。 Cycle()也调用Segment(),所以我添加了这个。每个周期有30个分段。 –