2012-01-05 95 views
2

我正在使用API​​,并且我有一个问题。我正在研究select_related()的用法,以便为自己节省一些数据库查询,事实上它确实有助于减少执行的数据库查询的数量,以及更复杂和更复杂的查询的费用。Django:select_related()和内存使用情况

我的问题是,使用select_related()会导致heasvier内存使用情况?运行一些实验,我发现确实如此,但我想知道为什么。不管我是否使用select_related(),响应将包含完全相同的数据,那么为什么使用select_related()会导致使用更多的内存?

是因为缓存吗?也许单独的数据对象用于缓存相同的模型实例?我不知道还有什么想法。

在此先感谢。

回答

6

这是一个折衷。将查询发送到数据库需要时间,数据库准备结果,然后将结果发回。 select_related的工作原理是这个过程中最昂贵的部分是请求和响应循环,而不是实际的查询,所以它允许你将原本不同的查询合并为一个,所以只有一个请求和响应,而不是多。但是,如果数据库服务器电源不足(没有足够的RAM,处理能力等),较大的查询实际上最终可能会比请求和响应周期花费更长的时间。如果出现这种情况,您可能需要升级服务器,而不是使用select_related

经验法则是,如果您需要相关数据,请使用select_related。如果实际速度不是很快,那么这就是您需要优化数据库的一个信号。

UPDATE(添加更多的解释)

查询数据库实际上包括多个步骤:

  1. 应用生成
  2. 查询被发送到数据库服务器(毫秒到查询(忽略不计)秒)
  3. 数据库处理查询(毫秒到秒)
  4. 查询资源(毫秒到秒)

在调整良好的环境(足够的服务器资源,快速连接)中,整个过程仅需几毫秒即可完成。但是,步骤2和步骤4通常比步骤3占用更多的时间。这就是为什么发送比多个更简单的查询更少的复杂查询更有意义:瓶颈通常是传输层而不是处理。

但是,对于拥有大型复杂表的动力不足的机器而言,数据库性能差的数据库可能需要很长时间才能运行查询,从而成为瓶颈。这最终会抵消发送一个复杂查询而不是多个简单查询所带来的时间减少,即数据库对较简单的查询响应更快,并且整个过程需要更少的净时间。然而,如果是这种情况,正确的响应是修复数据库端:优化数据库及其配置,添加更多的服务器资源等,而不是恢复发送多个简单查询。

+0

Chris,谢谢你的回应。一个后续问题;您提到:如果您的数据库服务器处于供电状态,则较大的查询实际上可能最终花费的时间比请求和响应周期更长。这是什么原因?请求/响应周期的较大查询需要多长时间?以及更大的查询如何消耗更多的内存?谢谢:) – 2012-01-05 22:53:17

+0

“较大”的查询,我的意思是一个更复杂(涉及连接等),不一定是实际查询的文本长度。然后数据库必须继续做许多额外的工作,从多个来源选择数据并将它们拼接在一起。另外,如果这些表格有许多列和/或行,可能会增加涉及的时间和处理。如果运行数据库的系统具有足够的资源,则不应超过几毫秒。但是,如果系统电源不足,导致内存溢出和分页,则可能需要更多时间。 – 2012-01-06 15:20:31

+0

梦幻般的答案:)我希望我可以upvote你更多! – 2012-01-07 12:20:19