2014-02-06 4 views
0

Использование Rails. Я пытаюсь использовать следующие строки для удаления database_a.shops где не найдено в database_b.properties:Сравнение двух больших наборов идентификаторов из разных таблиц для удаления

properties = Property.pluck(:id) 
Shop.where("property_id NOT IN (?)", properties).destroy_all 

Проблема с этим состоит в том, что database_a.shops и database_b.properties имеют более 500000 записей для сравнения, приводит к следующим ошибкам на втором запросе:

from /Users/abc/.rbenv/versions/1.9.3-p484/lib/ruby/gems/1.9.1/gems/activerecord-3.2.13/lib/active_record/connection_adapters/abstract_mysql_adapter.rb:245:in `query' 
    from /Users/abc/.rbenv/versions/1.9.3-p484/lib/ruby/gems/1.9.1/gems/activerecord-3.2.13/lib/active_record/connection_adapters/abstract_mysql_adapter.rb:245:in `block in execute' 
    from /Users/abc/.rbenv/versions/1.9.3-p484/lib/ruby/gems/1.9.1/gems/activerecord-3.2.13/lib/active_record/connection_adapters/abstract_adapter.rb:280:in `block in log' 
    from /Users/abc/.rbenv/versions/1.9.3-p484/lib/ruby/gems/1.9.1/gems/activesupport-3.2.13/lib/active_support/notifications/instrumenter.rb:20:in `instrument' 
    from /Users/abc/.rbenv/versions/1.9.3-p484/lib/ruby/gems/1.9.1/gems/activerecord-3.2.13/lib/active_record/connection_adapters/abstract_adapter.rb:275:in `log' 
    from /Users/abc/.rbenv/versions/1.9.3-p484/lib/ruby/gems/1.9.1/gems/activerecord-3.2.13/lib/active_record/connection_adapters/abstract_mysql_adapter.rb:245:in `execute' 
    from /Users/abc/.rbenv/versions/1.9.3-p484/lib/ruby/gems/1.9.1/gems/activerecord-3.2.13/lib/active_record/connection_adapters/mysql2_adapter.rb:211:in `execute' 
    from /Users/abc/.rbenv/versions/1.9.3-p484/lib/ruby/gems/1.9.1/gems/activerecord-3.2.13/lib/active_record/connection_adapters/mysql2_adapter.rb:215:in `exec_query' 
    from /Users/abc/.rbenv/versions/1.9.3-p484/lib/ruby/gems/1.9.1/gems/activerecord-3.2.13/lib/active_record/connection_adapters/mysql2_adapter.rb:224:in `select' 
    from /Users/abc/.rbenv/versions/1.9.3-p484/lib/ruby/gems/1.9.1/gems/activerecord-3.2.13/lib/active_record/connection_adapters/abstract/database_statements.rb:18:in `select_all' 
    from /Users/abc/.rbenv/versions/1.9.3-p484/lib/ruby/gems/1.9.1/gems/activerecord-3.2.13/lib/active_record/connection_adapters/abstract/query_cache.rb:63:in `select_all' 
    from /Users/abc/.rbenv/versions/1.9.3-p484/lib/ruby/gems/1.9.1/gems/activerecord-3.2.13/lib/active_record/querying.rb:38:in `block in find_by_sql' 
    from /Users/abc/.rbenv/versions/1.9.3-p484/lib/ruby/gems/1.9.1/gems/activerecord-3.2.13/lib/active_record/explain.rb:41:in `logging_query_plan' 
    from /Users/abc/.rbenv/versions/1.9.3-p484/lib/ruby/gems/1.9.1/gems/activerecord-3.2.13/lib/active_record/querying.rb:37:in `find_by_sql' 
    from /Users/abc/.rbenv/versions/1.9.3-p484/lib/ruby/gems/1.9.1/gems/activerecord-3.2.13/lib/active_record/relation.rb:171:in `exec_queries' 
    from /Users/abc/.rbenv/versions/1.9.3-p484/lib/ruby/gems/1.9.1/gems/activerecord-3.2.13/lib/active_record/relation.rb:160:in `block in to_a' 
    from /Users/abc/.rbenv/versions/1.9.3-p484/lib/ruby/gems/1.9.1/gems/activerecord-3.2.13/lib/active_record/explain.rb:41:in `logging_query_plan' 
    from /Users/abc/.rbenv/versions/1.9.3-p484/lib/ruby/gems/1.9.1/gems/activerecord-3.2.13/lib/active_record/relation.rb:159:in `to_a' 
    from /Users/abc/.rbenv/versions/1.9.3-p484/lib/ruby/gems/1.9.1/gems/activerecord-3.2.13/lib/active_record/relation.rb:498:in `inspect' 
    from /Users/abc/.rbenv/versions/1.9.3-p484/lib/ruby/gems/1.9.1/gems/railties-3.2.13/lib/rails/commands/console.rb:47:in `start' 
    from /Users/abc/.rbenv/versions/1.9.3-p484/lib/ruby/gems/1.9.1/gems/railties-3.2.13/lib/rails/commands/console.rb:8:in `start' 
    from /Users/abc/.rbenv/versions/1.9.3-p484/lib/ruby/gems/1.9.1/gems/railties-3.2.13/lib/rails/commands.rb:41:in `<top (required)>' 
    from script/rails:6:in `require' 
    from script/rails:6:in `<main>' 

Я пробовал использовать find_each, но он по-прежнему не работает и дает ту же ошибку. Я думаю, что эти множества слишком велики для сравнения. Как я могу это исправить?

Обратите внимание, что я не могу использовать необработанный SQL, потому что я хочу использовать destroy_all в Rails для уничтожения окружающих.

+0

Вы пробовали без массива? Например: 'Shop.where (" property_id NOT IN (SELECT id FROM properties "). Destroy_all' – MurifoX

+0

@MurifoX' properties' находится в другой базе. – Victor

+0

О, это проблема! Никогда не комментируйте мой комментарий. – MurifoX

ответ

0

Если операция выполняется один раз, может быть, вы могли бы принять некоторые медленную работу и сделать что-то вроде:

Shop.all.each do |shop| 
    shop.destroy unless Property.find(shop.property_id) 
end 

Если это не выполняется один раз, когда я предлагаю вам перепроектировать, чтобы избежать этой проблемы. Вы можете добавить целостность данных в класс свойств:

has_many shops, :dependent => :destroy 
Смежные вопросы