【问题标题】:how to display thousands of records如何显示数千条记录
【发布时间】:2025-12-10 08:25:02
【问题描述】:

我有一个名为 clientes 的表,这个表有大约 15536​​ 条记录,这使得数据加载非常缓慢。如何优化日志负载以改进流程?

这是我的索引视图

<h1>Clientes</h1>
<style>
.container {
}

</style>




  <table id="clientes" class="display"><!--el id clientes es de datatables referenciado en clientes.coffe y display class es una clase de datatables-->
  <thead>

    <tr><!--active es para sombrear la fila-->
      <th>Clave</th>
      <th>Nombre</th>
      <th>Nombre Corto</th>
      <th>Dirección</th>
      <th>Colonia</th>
      <th>Credito</th>
      <th>DiasCredito</th>
      <th>LimiteCredito</th>
      <th>Saldo</th>
      <th>Ruta</th>
      <th>Promociones</th>
      <th>Acción</th>
      <th></th>

    </tr>
  </thead>
    <tbody id="container_clientes">
      <%= render @clientes %><!--carga todos los clientes-->
</tbody>

我的部分cliente.html.erb

<tr id="cliente_<%= cliente.id %>">
  <td><%=cliente.IdCli%>

</td>
  <td><%=cliente.Nombre%></td>
  <td><%=cliente.NombreCorto%></td>
  <td><%=cliente.Direccion%></td>
  <td><%=cliente.Colonia%></td>
  <td>
    <% if cliente.Credito == true%>
      <input type="checkbox" disabled="true" checked="true">
    <%else%>
      <input type="checkbox" disabled="true" >
    <%end%>
  </td>
  <td><%=cliente.DiasCreedito%></td>
  <td><%=cliente.LimiteCredito%></td>
  <td>
    <% if cliente.detallecob.last != nil%>
        <%=cliente.detallecob.last.Saldo%>
      <%else%>
        <%=cliente.Saldo%>
    <%end%>
  </td>
  <td>
    <% if cliente.relclirutas != nil%>
      <% cliente.relclirutas.each do |varias| %>
        <%=varias.ruta.Ruta%>
      <%end%>
    <%end%>
  </td>
  <td>
    <% if cliente.relclili != nil%>
      <%=cliente.relclili.listapromomast.ListaMaster%>
    <%end%>
  </td>


    <td>
        <%= link_to '<i class="fa fa-gift" aria-hidden="true"></i> Activos'.html_safe, activos_cliente_path(cliente), class:"btn btn-primary btn-xs boton" %>

        <button type="button" class="btn btn-warning btn-xs" data-toggle="modal" data-target="#myupdatecliente_<%= cliente.id %>">
          Editar
        </button>
        <!--Destroy-->
        <% if cliente.Status == true%>
          <%= link_to 'Eliminar', cliente, method: :delete, class: "btn btn-danger btn-xs", remote:true %>
        <%else%>
          <%= link_to 'Habilitar', cliente, method: :delete, class: "btn btn-success btn-xs", remote:true %>
        <%end%>
      </td>


<td class="no" >
    </td>
</tr>

【问题讨论】:

  • 您是对数据进行分页还是一次加载?
  • 这是一个简单的决定。一方面,您可以一次将所有记录加载到浏览器中。加载需要多长时间取决于您无法控制的许多事情,例如用户的计算机。这可能值得等待。另一方面,您可以一次快速加载几条记录,并让用户选择一些内容以查看更多内容。与所有决策一样,每个选项至少比另一个具有优势。
  • @gaga5lala 只加载一次,在数据表中
  • @DanBracuk 你会推荐哪一个使用数据表?
  • 如果我是用户,我想查看每条记录。我可以使用浏览器的查找功能来查找特定内容。我不喜欢额外的鼠标点击。但是,我不是你的用户。

标签: sql ruby-on-rails ruby datatable


【解决方案1】:

您可以使用kaminari gem 进行数据分页,只需获取部分数据,访问下一页即可。

Cliente.page(1).per(50)

kaminari 也为你做分页链接,只需使用 helper

<%= paginate @cliente %>

你可以在README找到用法。

为了更好的用户体验,你应该让请求通过 API(AJAX)进行通信,并使用一些技术,比如无限滚动。

【讨论】:

    【解决方案2】:

    你可以卸载你的抓取。这意味着,对 javascript 和 ajax 使用稍微复杂一点的方法。在这个例子中我不会使用分页 gem。

    修改你的控制器:

    def index
        if !params[:page].blank?
            respond_to do |f|
                f.html {}
                f.json { # only for pagination, work around this to make it more complex
                    offset = 50*params[:page].to_i
                    @clients = Client.offset(offset).limit(50).select("field1, field2") # appended to any other condition you may have
                    render :json => @clients.as_json
                }
            end
        else
            @clients = Client.limit(50)
        end
    end
    

    我就不多发了,大家自行脑补。在文档加载时,添加一个 ajax fetch 事件,该事件将:

    • 调用 /clientes?page=2 等(添加增量计数器)
    • 执行以下操作,直到您得到空响应:
      • 对于您从 json 响应中获得的每一行,在部分代码之后在表中追加一行

    您可以使用计时器或循环来完成。但这是您的页面在加载第一组行(在本例中为 50 行)后响应的一种方式,然后在您工作时,将获取更多行。

    【讨论】:

    • 感谢您的回答。此方法使用数据表有效吗?
    • 什么是datatable?我在你的问题中看到的只是一个表格和每一行的渲染。根据您的问题,这应该可以工作...
    【解决方案3】:

    这有点猜测,因为我不是 ruby​​ 程序员,但是,让我们看看这个:

    <td>
        <% if cliente.relclirutas != nil%>
          <% cliente.relclirutas.each do |varias| %>
            <%=varias.ruta.Ruta%>
          <%end%>
        <%end%>
      </td>
    

    如果是这样的话,

    if cliente.relclirutas is not null or an empty string
    loop through it and display each value of varias.ruta.Ruta
    

    那么你就不需要 if 语句了。只需遍历空值或空字符串。这可能会在每条记录上为您节省几纳秒,其中您有 15,000 多条记录。

    【讨论】: