Ruby On Rails is slow…?

后端 未结 11 1810
说谎
说谎 2021-01-31 23:50

I\'m writing a web application to monitor a furniture factory production flow. It has thousand of data to handle. So far, I run RoR on Mongrel + MySQL and it\'s really really sl

相关标签:
11条回答
  • 2021-02-01 00:11

    There are some good screen casts on this topic http://railslab.newrelic.com/scaling-rails

    Things like fragmet caching and using :include (to avoid n+1) can help. It sounds like you're already using memcached, so why not curl the url to prefetch the cache?

    0 讨论(0)
  • 2021-02-01 00:12

    While R-n-R has a reputation of being slow, this sounds too extreme to be a simple problem with the language.

    You should run a profiler to determine exactly what functions are slow and why. The most common thing slowing down a web application is the "n+1 problem". That is, when you have n data items in your database, the app makes n separate queries to the database instead of making one query which gets them. But you can't know until you run the profiler. ruby-prof is one profiler I've used.

    Edit based on profile results edit:

    I firmly believe that you can always remove a query loop. As Mike Woodhouse says, the Rails way to do this is to specify the relations between your tables with a has_many or other association and then let rails automatically generate the table join, this is clear, fast and "the Rails way". But if you are starting out with bare SQL or if the associations don't work in this case, you can simply generate the appropriate joins yourself. And If all else fails, you can create a view or denormalized table which holds the results which previously were found through a loop. Indeed, the fact that you have to iterate through generated queries might be a sign that your table design itself has some flaws.

    All that said, if caching your query results works well enough for you, then stay with it. Optimize when needed.

    0 讨论(0)
  • 2021-02-01 00:17

    I'll agree with everyone else. You have to profile. There is no point in doing anything to your code until you know what specifically is causing the slowness. Trying to fixing a problem without understanding the cause is like feeling ill and deciding to have lots of surgery until you feel better. Diagnose your problem first. It might be something small like a network setting or it could be one bad line in your code.

    Some tips for profiling:

    How to Profile Your Rails Application

    Performance Testing Rails Applications

    At the Forge - Profiling Rails Applications

    Once you have found the bottleneck you can figure out what to do.

    I recommend these videos: Railslab Scaling Rails

    Revised now based on prof results:

    OK. Now that you can see that your problem is that you are doing some sort of calculation using a query based on looping through the results of another active record query I'd advise you to look into building a custom SQL statement combining your initial selection criteria and the loop calculation to get what you need. You can definitely speed this up by optimizing the SQL.

    0 讨论(0)
  • 2021-02-01 00:18

    How many of those 0-10ms queries are being executed per view access? What parts of your data model are being referenced? Are you using :include to get eager loading on your associations?

    Rails is as slow as you make it. With understanding comes speed (usually!)

    Expanding on the above, do you have has_many associations where, in particular, your view is referencing the "many" side without an :include? This causes your find(:all) on the master table to be executed with a join to the detail - if you have large numbers of detail records and are processing all of them individually, this can get expensive.

    Something like this:

    Master.find(:all, :include => :details)
    

    ...might help. Still guessing from sparse info, though.

    There's an old Railscast on the subject here

    0 讨论(0)
  • 2021-02-01 00:19

    You might profile the code first before doing anything, though, queries inside for loops are a very common cause for performance problems and at first sight this seems your problem. You might anyway find a practical profiler here:

    As already said on the other answers, if both models are related you should eager load the associations, which implies instructing Active Record to perform join queries:

    #left outer join
    ofkbs=Ofkb.includes(:operation).where(name: "banana")
    

    If you do not need the ofkbs but only the operations, you could perform an inner join

    #inner join (discards the Ofkbs that do not have any operation)
    operations=Operation.joins(:ofkb).where(ofkb:{name:"banana"})
    

    This solution only preforms one query, and allows you to afterwards iterate through the data that will have already been collected from the DB:

    operations=ofkbs.map{|of| of.operations}.flatten
    
    operations.each do |o|
      do_whatever_you_want_with_operation(o)
    end
    

    If the queries are very complicated you should use arel instead.

    0 讨论(0)
提交回复
热议问题