Peter - lets switch boxes!
I am glad to here you are having
success with your setup - we have a good problem of a successful web
app - so traffic continually is increasing - I just pray we dont get
digged or slashdotted (yet at least).
Postgres - by far - then apache - to answer the other comment - slow
all the time - we have an international user group - but traffic is
def. slower at 1 am than at noon PST - however even when I am on the
site at night around midnight still super slow.
Phil - here is a little sampling from out log (im removed the url to
our site for now)
Processing HumansController#my_account (for 24.41.63.235 at 2008-02-21
18:42:37) [GET]
Session ID: 17fa2835e51d3e67a7ad1d8e031f3a4d
Parameters: {âactionâ=>âmy_accountâ, âcontrollerâ=>âhumansâ}
Rendering within layouts/setup
Rendering humans/my_account
Completed in 2.92013 (0 reqs/sec) | Rendering: 0.03056 (1%) | DB:
2.42590 (83%) | 200 OK [http://www.website.com/shop/browse/womens?
page=11]
Completed in 0.20057 (4 reqs/sec) | Rendering: 0.10504 (52%) | DB:
0.09320 (46%) | 200 OK [http://www.website.com/humans/my_account/]
Rendering within layouts/setup
Rendering home/index
Rendering within layouts/setup
Rendering shop/browse
Completed in 0.86887 (1 reqs/sec) | Rendering: 0.09286 (10%) | DB:
0.67580 (77%) | 200 OK [http://www.website.com/]
Rendering within layouts/setup
Rendering vote/in_the_running_day
It really does sound a query tuning issue. It comes in two forms. The
first the prototypical indexing issue. For example, when navigating
across a relationship:
@parent = SomeClass.find(params[:id])
@children = @parent.children
The child table will have some_class_id, which needs to be indexed.
When you migrate and add tables Rails/postgres automatically generates
primary keys for id fields. It does not generate indexes on all the
foreign key fields. So, the generated :
SELECT * FROM WHERE some_class_id = 37
Will scan the entire table.
The second problem, which may or may not apply to you, is what is called
a âcross-productâ query. For example, in a find method you join to
another table but donât add a restriction for the join columns. A cross
product query between two tables, each with 1000 rows, will generate an
intermediate result on the order of 1,000,000 records.
How to find you have a query problem.
- You can isolate your queries, run them in a postgres console and see
how long they take or do an âexplain plan.â - Examine your log for places where the time spend in the database is
more than a fraction of a second.
It may take a little while to find since a page may generate a dozen
queries, only one of which is bad. It may not even be on every page.
cartesian product - eh? we may have some brutally poor joins in our
queries I really appreciate everyones insights and comments - super
valuable information - at least gives us some places to get started.
Completed in 2.92013 (0 reqs/sec) | Rendering: 0.03056 (1%) | DB:
2.42590 (83%) | 200 OK [http://www.website.com/shop/browse/womens?
page=11]
You should figure out what in this request is taking the database 2.4
seconds to complete⌠thatâs a long timeâŚ
Completed in 0.86887 (1 reqs/sec) | Rendering: 0.09286 (10%) | DB:
0.67580 (77%) | 200 OK [http://www.website.com/]
Donât know what your site does, but maybe you could page cache the
homepage for a couple of minutes at a time? We do that and it gains us
quite a bit.
Marc wrote:
2.42590 (83%) | 200 OK [http://www.website.com/shop/browse/womens?
page=11]
more than 2s in DB ?!?
On most web applications ever to scale a DB query should take less than
0.01s
So 2 questions to answer :
1/ How many DB queries are you doing for this page?
2/ Are there some DB queries taking more than a few ms?
To check this, dump your db, reload it in your development environment,
browse the pages while watching the development.log file, youâll get a
listing of all SQL queries with the time spent in DB.
If you do too many queries, check if you can use :include in your
ActiveRecord::Base.find calls to reduce the need to fetch associations
with other queries later. Verify that you get a benefit doing so (I
actually saw PostgreSQL being faster when fetching associations later on
tricky queries but 99% of the time it should be a huge win).
If some queries are slow, depending on what you are used to, go into
pgadmin or psql and âEXPLAIN queryâ. Then youâll have to be a DBA -![]()
Adding indexes on the proper column or column combinations can make the
difference between a page taking 3s and a page taking 0.05s to renderâŚ
You should now that PostgreSQL becomes faster each time they release a
new minor version since around 7.0. Switching from 8.0 to 8.2 helped
quite a bit here.
Iâm not sure if ruby-postgres is OK with 8.3 (I remember there where
problems being addressed recently). 8.2 is fine.
You definitely should use migrations to add/remove indexes, itâs easier
to maintain your dev/test boxes in sync with the production for
performance testing this way (and you can document why an index is
needed).
Lionel
Lionel - thank you so much for the great advice - we have serious
query issues - as you can see below - i am reviewing the production
log right now and we are consistently looking at 1.5 - 4 seconds in
some cases for scrips to run
On Feb 22, 3:00 pm, Lionel B. [email protected]
Friends- thank you again for all your help - we just migrated and we
just re-indexed and saw a significant increase in speed - however - we
will be taking all the comments here on this post to heart and putting
together a scaling plan - thanks again to everyone for the quick
responses and great insight!
This plugin may interest you:
http://agilewebdevelopment.com/plugins/sql_logging
IMO, best run in production mode with log level set to DEBUG.
Howdy Ezra -
On Feb 22, 3:45 pm, Ezra Z. [email protected] wrote:
studies anyone has had - thanks for your time in posting!
May I humbly suggest getting a copy of my book that was just finishedyesterday? http://pragprog.com/titles/fr_deploy It covers taking a
rails app form infancy to maturity and covers all the topics of
scaling out like apache/nginx/mongrel as well as Xen and mysql master -slave and master â master.
Cheers-
- Ezra Z.
If you donât mind Ezra, having just read through your performance
tuning chapter a few questions came to mind?
First you donât mention HAproxy - I think (?) you once recommended
it. Do you now feel that nginx serves well on the front end?
Weâve deployed haproxy â many nginx â mongrel
Is the above configuration problematic?
I also noticed (perhaps related to the above) some conf settings that
I donât share.
A. under events, youâre using worker_connections 8192. Every other
example (including my own) have them set to 1024.
Iâve looked around but havneât found a decent guide to setting this
value
B. use epoll
How does the event drive poller (epoll) assist ?
thanx for your thoughts Ezra. Congrats on the book - looking forward
to seeing how you treated the Capistrano chapter. grin.
I have a few more questions about the book - namely the performance
tuning chapter. Whereâs the best place to ask more?
Jodi