包括

时间:2017-07-04 09:41:58

标签: ruby-on-rails ruby

我对这种代码采取了行动:

  Timesheet::WorkPeriod.includes(:ship).limit(2000).to_a
  render nothing: true

服务器答案给出:

method=GET path=/timesheet_reports/rest_hours format=html controller=Company::Timesheet::ReportsController action=rest_hours status=200 duration=2106.43 view=3.68 db=23.75

但是,在浏览器中,渲染需要6秒(对于空白)页面。如果我将2000更改为更高的值,则会有4秒的差异。

如果我删除了includesto_a,这是正确的。如果我这样做的话也一样:

Timesheet::WorkPeriod.includes(:ship).limit(2000).each(&:id)

即使存在n + 1个查询问题,删除包含也是最快的。

我使用的是ruby 2.3和Rails 4.2。

我认为内存分配存在问题,但我不知道如何解决它。我该怎么办?

2 个答案:

答案 0 :(得分:0)

为什么使用包含? SQL看起来像什么? 也许如果您阅读sql,您会看到:

Timesheet::WorkPeriod.includes(:ship)
# SELECT "work_period".* FROM "work_period"
# SELECT "ship".* FROM "ship" WHERE "ship"."work_period_id" IN (....)

如果您有很多行,查询的成本可能很高!

另外因为你的结果可能很大。操作ruby中的巨大阵列需要花费。

在使用ruby之前,尽量使用尽可能多的活动记录方法,例如:

Timesheet::WorkPeriod.includes(:ship).limit(2000).each(&:id)
# use select if you need AR object
Timesheet::WorkPeriod.includes(:ship).limit(2000).select(:id)
# or pluck if you need the list of value in column
Timesheet::WorkPeriod.includes(:ship).limit(2000).pluck(:id)

当您访问页面时,还要检查日志,看看您是否没有N + 1。宝石bullet也可以帮助你。 如果它没有帮助你。使用rack-mini-profiler

进一步阅读:

答案 1 :(得分:0)

确保您的关系已编入索引。而且,使用pluck而不是每个。

<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">

    <xsl:output indent="yes"/>
    <xsl:strip-space elements="*"/>

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="line">
        <xsl:apply-templates/>
    </xsl:template>

    <xsl:template match="sequence"/>

    <xsl:template match="section | field">
        <xsl:element name="{name}">
            <xsl:apply-templates select="* except name"/>
        </xsl:element>
    </xsl:template>

    <xsl:template match="*[name]/value">
        <asCurrent>
            <xsl:apply-templates/>
        </asCurrent>
    </xsl:template>

    <xsl:template match="table">
        <xsl:element name="{name}">
            <xsl:apply-templates select="* except name"/>
            <maxPK>
                <xsl:value-of select="count(tableRow)"/>
            </maxPK>
        </xsl:element>
    </xsl:template>

    <xsl:template match="tableRow">
        <xsl:element name="{field/name}">
            <xsl:apply-templates select="* except name"/>
        </xsl:element>
    </xsl:template>

    <xsl:template match="tableRow/sequence">
        <pk>
            <xsl:apply-templates/>
        </pk>
    </xsl:template>

    <xsl:template match="tableRow/field[name = 'secondaryPhone']">
        <phone>
            <xsl:apply-templates select="value"/>
        </phone>
    </xsl:template>

</xsl:transform>

如果索引正常,请仔细检查是否所有数据都是必需的。如果您需要的只是一个ID,请随意使用联接并仅选择ID。

Timesheet::WorkPeriod.includes(:ship).limit(2000).pluck(:id)
# Depending which ID you need
Timesheet::WorkPeriod.includes(:ship).limit(2000).pluck('ships.id')