Neo4j.rb - индекс разбивается на Kaminari слишком медленно

Вот мой контроллер (индекс отсортирован):

  def index
    if params[:limit]
      @bisacs = Bisac.order(:bisac_code).page(params[:page]).per(params[:limit])
    else
      @bisacs = Bisac.order(:bisac_code).page(params[:page])
    end
  end

Вот выполненные запросы (слишком много, на мой взгляд, и слишком медленные, 6-7 секунд для первой страницы или для перехода к следующей/последней):

Started GET "/bisacs" for 127.0.0.1 at 2015-08-11 13:16:33 -0400
Processing by BisacsController#index as HTML
  Rendered home/_main_links.html.erb (0.2ms)
 CYPHER 358ms MATCH (result_bisac:`Bisac`) RETURN count(result_bisac) AS result_bisac 
 CYPHER 389ms MATCH (result_bisac:`Bisac`) RETURN result_bisac ORDER BY result_bisac.bisac_code SKIP {skip_0} LIMIT {limit_25} | {:skip_0=>0, :limit_25=>25}
 CYPHER 119ms MATCH n WHERE (ID(n) = {ID_n}) WITH n RETURN ID(n) | {:ID_n=>24319299}
 CYPHER 118ms MATCH n WHERE (ID(n) = {ID_n}) WITH n RETURN ID(n) | {:ID_n=>24319299}
 CYPHER 118ms MATCH n WHERE (ID(n) = {ID_n}) WITH n RETURN ID(n) | {:ID_n=>24320808}
 CYPHER 118ms MATCH n WHERE (ID(n) = {ID_n}) WITH n RETURN ID(n) | {:ID_n=>24320808}
 CYPHER 120ms MATCH n WHERE (ID(n) = {ID_n}) WITH n RETURN ID(n) | {:ID_n=>24319262}
 CYPHER 118ms MATCH n WHERE (ID(n) = {ID_n}) WITH n RETURN ID(n) | {:ID_n=>24319262}
 CYPHER 118ms MATCH n WHERE (ID(n) = {ID_n}) WITH n RETURN ID(n) | {:ID_n=>24320349}
 CYPHER 120ms MATCH n WHERE (ID(n) = {ID_n}) WITH n RETURN ID(n) | {:ID_n=>24320349}
 CYPHER 120ms MATCH n WHERE (ID(n) = {ID_n}) WITH n RETURN ID(n) | {:ID_n=>24318456}
 CYPHER 119ms MATCH n WHERE (ID(n) = {ID_n}) WITH n RETURN ID(n) | {:ID_n=>24318456}
 CYPHER 119ms MATCH n WHERE (ID(n) = {ID_n}) WITH n RETURN ID(n) | {:ID_n=>24320054}
 CYPHER 116ms MATCH n WHERE (ID(n) = {ID_n}) WITH n RETURN ID(n) | {:ID_n=>24320054}
 CYPHER 119ms MATCH n WHERE (ID(n) = {ID_n}) WITH n RETURN ID(n) | {:ID_n=>24321703}
 CYPHER 119ms MATCH n WHERE (ID(n) = {ID_n}) WITH n RETURN ID(n) | {:ID_n=>24321703}
 CYPHER 118ms MATCH n WHERE (ID(n) = {ID_n}) WITH n RETURN ID(n) | {:ID_n=>24319503}
 CYPHER 117ms MATCH n WHERE (ID(n) = {ID_n}) WITH n RETURN ID(n) | {:ID_n=>24319503}
 CYPHER 118ms MATCH n WHERE (ID(n) = {ID_n}) WITH n RETURN ID(n) | {:ID_n=>24321755}
 CYPHER 118ms MATCH n WHERE (ID(n) = {ID_n}) WITH n RETURN ID(n) | {:ID_n=>24321755}
 CYPHER 116ms MATCH n WHERE (ID(n) = {ID_n}) WITH n RETURN ID(n) | {:ID_n=>24319313}
 CYPHER 118ms MATCH n WHERE (ID(n) = {ID_n}) WITH n RETURN ID(n) | {:ID_n=>24319313}
 CYPHER 118ms MATCH n WHERE (ID(n) = {ID_n}) WITH n RETURN ID(n) | {:ID_n=>24321376}
 CYPHER 119ms MATCH n WHERE (ID(n) = {ID_n}) WITH n RETURN ID(n) | {:ID_n=>24321376}
 CYPHER 119ms MATCH n WHERE (ID(n) = {ID_n}) WITH n RETURN ID(n) | {:ID_n=>24321021}
 CYPHER 118ms MATCH n WHERE (ID(n) = {ID_n}) WITH n RETURN ID(n) | {:ID_n=>24321021}
 CYPHER 123ms MATCH n WHERE (ID(n) = {ID_n}) WITH n RETURN ID(n) | {:ID_n=>24319280}
 CYPHER 119ms MATCH n WHERE (ID(n) = {ID_n}) WITH n RETURN ID(n) | {:ID_n=>24319280}
 CYPHER 118ms MATCH n WHERE (ID(n) = {ID_n}) WITH n RETURN ID(n) | {:ID_n=>24318845}
 CYPHER 118ms MATCH n WHERE (ID(n) = {ID_n}) WITH n RETURN ID(n) | {:ID_n=>24318845}
 CYPHER 122ms MATCH n WHERE (ID(n) = {ID_n}) WITH n RETURN ID(n) | {:ID_n=>24320822}
 CYPHER 119ms MATCH n WHERE (ID(n) = {ID_n}) WITH n RETURN ID(n) | {:ID_n=>24320822}
 CYPHER 118ms MATCH n WHERE (ID(n) = {ID_n}) WITH n RETURN ID(n) | {:ID_n=>24318841}
 CYPHER 118ms MATCH n WHERE (ID(n) = {ID_n}) WITH n RETURN ID(n) | {:ID_n=>24318841}
 CYPHER 119ms MATCH n WHERE (ID(n) = {ID_n}) WITH n RETURN ID(n) | {:ID_n=>24321956}
 CYPHER 117ms MATCH n WHERE (ID(n) = {ID_n}) WITH n RETURN ID(n) | {:ID_n=>24321956}
 CYPHER 118ms MATCH n WHERE (ID(n) = {ID_n}) WITH n RETURN ID(n) | {:ID_n=>24319031}
 CYPHER 119ms MATCH n WHERE (ID(n) = {ID_n}) WITH n RETURN ID(n) | {:ID_n=>24319031}
 CYPHER 118ms MATCH n WHERE (ID(n) = {ID_n}) WITH n RETURN ID(n) | {:ID_n=>24320070}
 CYPHER 118ms MATCH n WHERE (ID(n) = {ID_n}) WITH n RETURN ID(n) | {:ID_n=>24320070}
 CYPHER 118ms MATCH n WHERE (ID(n) = {ID_n}) WITH n RETURN ID(n) | {:ID_n=>24322195}
 CYPHER 116ms MATCH n WHERE (ID(n) = {ID_n}) WITH n RETURN ID(n) | {:ID_n=>24322195}
 CYPHER 118ms MATCH n WHERE (ID(n) = {ID_n}) WITH n RETURN ID(n) | {:ID_n=>24319124}
 CYPHER 118ms MATCH n WHERE (ID(n) = {ID_n}) WITH n RETURN ID(n) | {:ID_n=>24319124}
 CYPHER 119ms MATCH n WHERE (ID(n) = {ID_n}) WITH n RETURN ID(n) | {:ID_n=>24322258}
 CYPHER 118ms MATCH n WHERE (ID(n) = {ID_n}) WITH n RETURN ID(n) | {:ID_n=>24322258}
 CYPHER 118ms MATCH n WHERE (ID(n) = {ID_n}) WITH n RETURN ID(n) | {:ID_n=>24318767}
 CYPHER 121ms MATCH n WHERE (ID(n) = {ID_n}) WITH n RETURN ID(n) | {:ID_n=>24318767}
 CYPHER 118ms MATCH n WHERE (ID(n) = {ID_n}) WITH n RETURN ID(n) | {:ID_n=>24320583}
 CYPHER 118ms MATCH n WHERE (ID(n) = {ID_n}) WITH n RETURN ID(n) | {:ID_n=>24320583}
 CYPHER 118ms MATCH n WHERE (ID(n) = {ID_n}) WITH n RETURN ID(n) | {:ID_n=>24319086}
 CYPHER 117ms MATCH n WHERE (ID(n) = {ID_n}) WITH n RETURN ID(n) | {:ID_n=>24319086}
  Rendered bisacs/index.html.erb within layouts/application (6722.1ms)
Completed 200 OK in 7096ms (Views: 7095.5ms)

Как это можно улучшить? Почему эти 25 узлов выбираются один за другим?

Чтобы получить все коды 3983 в консоли Neo4j, требуется всего 1 секунда или около того:

MATCH (result_bisac:`Bisac`) RETURN result_bisac ORDER BY result_bisac.bisac_code;
Returned 3983 rows in 1064 ms, displaying first 1000 rows.

person LDB    schedule 11.08.2015    source источник


Ответы (2)


Хм, хорошо, так что это еще один несколько смущающий ответ;)

Если вы поместите следующее в свою конфигурацию (либо в config/environments/development.rb, либо в config/application.rb), это должно исправить это:

config.neo4j._active_record_destroyed_behavior = true

Объяснение: гем реализует метод ActiveNode#exists? немного иначе, чем метод ActiveRecord#exists?. В ActiveRecord он просто проверяет, был ли объект уничтожен в какой-то момент в памяти. В ActiveNode мы выполняли проверку фактической базы данных (и, возможно, в какой-то момент нам нужно кэширование запросов).

Короче говоря, мы не хотели вводить это изменение сразу, потому что это критическое изменение, поэтому я добавил переменную конфигурации, которая на данный момент это исправляет. Переменная конфигурации не должна быть необходимой в версии 6.0.

person Brian Underwood    schedule 11.08.2015
comment
Работал идеально. Выполняется только один запрос на чистое шифрование (вместо многих): Начато GET /bisacs?page=5 для 127.0.0.1 Обработка BisacsController#index как HTML Параметры: {page=›5} Отображено home/_main_links.html.erb (0.2 мс) CYPHER 124ms MATCH (result_bisac:Bisac) RETURN count(result_bisac) AS result_bisac CYPHER 367ms MATCH (result_bisac:Bisac) RETURN result_bisac ORDER BY result_bisac.bisac_code SKIP {skip_100} LIMIT {limit_25} | {:skip_100=›100, :limit_25=›25} Визуализация bisacs/index.html.erb в макетах/приложении (526,8 мс) Выполнено 200 OK за 886 мс (Просмотры: 885,1 мс) - person LDB; 11.08.2015

Я прокомментировал следующие первые 3 строки в теге в представлении, и скорость стала приемлемой, около одной секунды:

<% @bisacs.each do |bisac| %>
  <tr>
    <td><%#= link_to 'Show', bisac %></td>
    <td><%#= link_to 'Edit', edit_bisac_path(bisac) %></td>
    <td><%#= link_to 'Destroy', bisac, method: :delete, data: { confirm: 'Are you sure?' } %></td>
    <td><%= bisac.bisac_code%></td>
    <td><%= bisac.bisac_value%></td>
  </tr>
<% end %>

Однако добавление ссылки обратно в «show» снова делает рендеринг страницы очень медленным:

<% @bisacs.each do |bisac| %>
  <tr>
    <td><%= link_to bisac.bisac_code, bisac%></td>
    <td><%= bisac.bisac_value%></td>
  </tr>
<% end %>
person LDB    schedule 11.08.2015