Database Optimization

Do you have a question? Post it now! No Registration Necessary.  Now with pictures!

Threaded View
Hello group,

I have a rather general but interesting inquiry that is related to PHP
and I hope this is the appropriate place to post it.

I'm looking for a way to improve dramatically the performance of my PHP
application. The application is getting slow as it is taking more load.
It is performing a very high number of queries to a database, and I
believe that this is taking up most of the ressources.

I'm trying to figure out how I could cache the content of the database
and prevent that many queries to be performed.

What I would like to do is cache all the content of the database in
memory, so that I could access it directly through my PHP application
without querying the database and saving precious ressources.

The database is quite small, 15 - 20 mB and it's size is constant (it
does not get bigger over time). 92% of the queries are SELECT, only 8
percents are UPDATE, DELETE and INSERT.

So, my question is, is it possible and recommandable to place 20mB of
data in shared memory in order to prevent queries to the database? (all
updates, deletes and inserts are performed both in the database as well
as in memory)

Or would I be better to place a copy of the database on a ramdrive?

Other info:
I have a server which runs both the PHP application and the MySQL
database. It has 1GB of RAM. The database receives 250 queries / sec.

Thank you in advance for your kind help

Re: Database Optimization wrote:

Quoted text here. Click to load it


I am unsure if placing the database in memory will seriously increase it's  
performance: you'll have to test that.

If you database is using its time on scanning tables and joining, and  
conversions, etc etc, the time trimmed off could be disappointing.
If the database is non-stop reading files, it could help.
Hard to say.
Which database do you use?

(!)But before you go all that way, did you try some more 'old-fashioned'  

Some ideas:
- Try to figure out which tables are scanned a lot, and place indexes on the  
relevant column(s).
(If you use Postgresql, try EXPLAIN-command for help)

- Does you DB and your code use Prepared statements?
They can help a lot, especially when the queries are complex.

- If 50 of the 250 queries/sec are the same selects that don't change, you  
could try some smart caching.
eg: If a popular query is to get the latest 20 this-or-that, with all kind  
of joins on other tables, you could shedule that query every 15 minutes,  
and safe the results in a file. Then include the file on the pages where  
you need it.
Alternatively: you could just update the file, whenever you know a relevant  
table is changed.
(What makes the most sense is up to you to decide of course.)

This kind of optimalization can make huge differences.

In general: Try to figure out which queries are executed a lot, and start  
there with prepared statements/indexing/caching-to-file.

Hope this helps.

Good luck!

Erwin Moller

Re: Database Optimization

Thanks for your reply.

I use a MySQL database that is properly optimized. All the indexes are
set correctly and used.

Most of the requests are simple queries using a unique ID and returning
only a single result. There is almost no joins or complex joins.

Quoted text here. Click to load it

Unfortunately, most of the the queries are different.

I can give an example:

An user table with around 4000 users. It is possible to consult other
user's information. So a lot of queries are made on single records.

 I tested placing a few records in memory with shm functions, and it
was of course, blazingly fast.

But I'm wonderig how the system reacts with higher volume of data, and
what would be the best way to do this.


Re: Database Optimization

Testing it could be easy. Have a link on the page that peeps currently
use asking them to test the effectiveness of the new code. I have
experienced that almost 80% of my users will go in and test the new
stuff, just for curiosity maybe. So my testing on new code is normally
completed within a few days, with no impact on operations.

Re: Database Optimization


But I would rather stick to profiling. It's much more precise.

Perhaps I should rewrite the exact question: is it possible and
recommandable to load large amount of data (20mB) into shared memory.
If yes, what is a good way to implement it.

Thanks again for your help

Re: Database Optimization wrote:
Quoted text here. Click to load it

8% is still a significant amount of writes. I wonder if your database
is running into locking problems. Not an expert in MySQL, but I've
heard that its locking mechanism isn't that great. If a table is
constantly being modified, then queries on it could be often stalled.

Re: Database Optimization

I do not use any manual locking as I do not need atomic transactions.
So I think locking shouldn't be an issue.

I believe that the source of the problem is the big amount of queries
generated by the mass of users. And that's why i'm looking at shared
memory caching.

Re: Database Optimization wrote:
Quoted text here. Click to load it

I'm not terrible familiar with MySQL. Perhaps someone can correct me if
I'm wrong. I think MySQL uses table locks for write operations. So you
could have situations wheere a select is blocked by a pending insert
which itself is blocked by an outstanding query.

I would research the topic of MySQL optimisation a bit more before
rolling your own shared memory system.

Re: Database Optimization

Maybe my article at
describes something useful. Especially the section on lazy collections  
can be interesting.

Best regards. wrote:
Quoted text here. Click to load it

Re: Database Optimization

That's right. It is interesting. This article touches the kind of
structure I would need for my caching solution.

As you mentionned, I want the class to control the data, no matter if
it comes from the database or from the cache. But I want it to control
all the updates, inserts, and deletes also as my data will never be
modified from outside of the application. The cache will simply be
updates at the same time as the database.

What I would like to discuss, however, is technically how to index,
retrieve, update and store large amount of data in shared memory.

Thanks for your help

Re: Database Optimization wrote:
Quoted text here. Click to load it
Is the amount of data that large? How come? I'd think that many webpages  
are not that large, as web page authors tend to cut the data in quickly  
readable chunks. Don't load into memory what you don't need.

If you use collection classes for your data, you effectively createyour  
own joins, but in a flexible way. You can decide for each collection  
(table) if it is retrieved lazily or greedily.

I noticed that I don't use much SQL JOINs anymore, as the join is  
effectively managed by the collection classes. For reading data,  
"HANDLER" is my favourite command nowadays. You can't get much faster  
than that. The latest thing I am playing with is a "preload" function on  
a lazy collection that groups as much requests into one batch (IN clause).
Anyhow, the collections remove many of the duplicate values that you  
would otherwise have in an SQL join.

On how to index, the subcollections mentioned in the article can be  
useful. If you have a tree-like data structure, subcollections are a  
very fast and natural way to organize your data.

Maybe it is useful to give a more detailed description of the kind of  
data your web page is managing.

Best regards

Re: Database Optimization wrote:
Quoted text here. Click to load it

It sounds like you could improve you performance by using query
caching and/or better indexing...  Read "High Performance MySQL"
by Jeremy Zawodny; it should give you some ideas...

Quoted text here. Click to load it

Yes, it is possible.  MySQL supports HEAP tables that are stored in
memory.  But you still need to figure out a way to save those tables
on the hard drive, because HEAP tables disappear when MySQL server
stops or reboots.

Quoted text here. Click to load it

Again, you can do that, but you still need to make sure your database
is synchronized to a hard drive somewhere...

Quoted text here. Click to load it

It appears a very manageable load...  How many concurrent connections
are you handling?  


Re: Database Optimization

First of all, thanks for your help.

Quoted text here. Click to load it

Even though not an expert, I know quite a bit about database
optimization, so I believe I can affirm that my database is quite

Quoted text here. Click to load it

That's right, I have no problems with synchronizing the regular tables
with HEAP tables. So this is an interesting solution. I was wondering
however, if I could gain more speed by skipping MySQL altogether and
using shared memory (Therefore saving communication between php and
mysql, SQL parsing, etc)?

Quoted text here. Click to load it

We have about 300 concurrent users at peak time and about 150 on
average. During peak, the number of queries/sec is more than 250
(perhaps 350?) and the server slows down a little bit but it is still
acceptable.  What we would like to do is optimize in order to be able
to accept more users at the same time.

Up to now, It still seems like loading the entire database in shared
memory could be an interesting solutions.

Thank you

Re: Database Optimization wrote:


Quoted text here. Click to load it


You could have a look a databases that are designed to run in momory, like  

They claim very fast performance.

Good luck,
Erwin Moller

Re: Database Optimization wrote:
Quoted text here. Click to load it

Oracle real application clusters.

Lots of Greetings!

Re: Database Optimization wrote:
Quoted text here. Click to load it

You really haven't provided enough information to get any meaningful  
help.  But I'll give it a try.

I see several possibilities:

   a) Get faster disks (or a RAID array).
   b) Further optimize your database and queries (maybe not possible).
   c) Upgrade to Oracle, DB2 or (under Windows) SQ Server.
   d) If running Windows, use Unix
   e) Put your database on a different machine.

Or a combination of the above.  And this is just off the top of my head  
- there are a lot of other possibilities.

You could run the database from shared memory, but only if it is 100%  
read only - no writes are ever done to it.

Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.

Re: Database Optimization wrote:

Quoted text here. Click to load it

   Faith should not be an issue here.  You need to get your load display  
tools out, and see where the bottleneck is.  This will vary on your OS.  
  Look out for disk transactions, and also for raw data transfers.

Quoted text here. Click to load it

   With MySQL, you could try to edit my.cnf and radically increase the  
cache sizes. Storing entire DB in cache will help, but only if you  
really had disk bottlenecks somewhere.

Quoted text here. Click to load it

   Most likely: NO.

   You would have to be absolutely pedanitc about making sure your  
server doesn't crash (loads of UPS behind it, make sure OS is stable  
enough, etc).

   Since you are doing very much selects, and your hardware can't copy,  
you could also try to build DB replication, and split the SELECT queries  
between multiple servers.  But that's a bit of work, so I'd suggest  
trying something else first.


Re: Database Optimization


on 09/15/2005 11:08 AM said the following:
Quoted text here. Click to load it

You may want to read about this exact subject in the Metabase PHP  
database abstraction FAQ. You are in the right track on seeking caching  
mechanisms but there is a lot more to be said:


Manuel Lemos

PHP Classes - Free ready to use OOP components written in PHP

PHP Reviews - Reviews of PHP books and other products

Metastorage - Data object relational mapping layer generator

Re: Database Optimization

Thank you,

This link was quite ressourceful.

They say that :

"On common solution for single server sites is to cache the content in
local disk files or shared memory. Shared memory is faster but its
availability may be too limited."

I guess that "too limited" means that caching big amount of data can be
hard and could be unreliable.

Perhaps file caching could be another option...

Re: Database Optimization

Recently I was faced with a challenging query (a join between three
100k line tables)
After some tweaking around, I found out that one problem I had was to
try and sotre more queries in memory (somebody had tweaked the my.cnf
file to store all it could in memory)
This bottle neck actually occured because all the memory got exhausted
after some use and the system started using virtual memory (swap) to
store the queries.
I guess this same rule could apply to you. When physical (ram) memory
exhausts, the system will resort to SWAP, causing a slower response
time in your system.
You'd probably be better off trying to limit the number and size of
queries being executed...
Reduce the memory usage in my.cnf and prefer to use a per query memory
limit by running the "SET SESSION read_buffer_size=#of_bytes"
before running the query. This will set memory allocation only to a
specific query, thus, reducing overall memory consumption.

Site Timeline