【发布时间】:2017-08-09 17:01:02
【问题描述】:
我会尽力解释我的问题。我遇到了性能问题,我想知道是否有更好的设置方法。
我有一个数据库,其中包含大约 150 年的逐年数据。每行大约有 10 列。
我每 30 年跨度运行一次“模拟”(我们将每个 30 年的块称为“周期”)。因此,第 1 周期将是 1-31 年。第 2 周期将是 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 时,我看到它正在执行 30 个单独的调用(每个数据点 1 个)(每个调用都使用“WHERE EXTRACT(MONTH FROM”,我相信这是我的 .yearly( ) 过滤器被调用。但它也在 Cycle() 中记录了一个查询,它实际上是按日期查找数据点。
当我像这样传递部分查询集时,数据是否被缓存?我的应用程序真的在运行 3000 个查询(使用数据库上的连接)还是在我的 DataPoint.objects.all().yearly() 调用中运行 1 个大查询,而其他所有查询都在内存中?
我试图了解为什么它运行得如此缓慢。我认为,部分问题是我正在创建这个庞大的对象列表: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 类的代码吗?更好地了解您的问题
-
完成。 Cycle() 也调用 Segment() 所以我添加了它。每个周期有 30 个段。