I was taught a simple lesson in the power of database indexes today. Here's how it happened: for a while, one of the sites I'm responsible for seemed to become slower and slower over time, even to the point of timing out during a database query. I always figured that it was because the web server was over 5 years old and needed a re-install or something like that. So, I switched to a new server and migrated the database to the new machine, which has more RAM and an has a more modern version of MySQL.
But guess what occurred on the new server when I started testing on it? The site and its database were as slow as ever. At that point I could no longer blame the problem on the machine, so that left... me. I had to figure that code optimization and/or database optimization were the only issues that could be at fault. So, I fired up a browser and looked at the MySQL docs. I knew enough to start investigating indexes to get things working a little faster, so one of the first lines I saw was this:
Use of indexes on the relevant columns is the best way to improve the performance of SELECT operations.
That was enough to convince me I was in the right place. I looked up the
CREATE INDEX syntax, and started to create indexes for the columns that showed up in my most common joins. Bingo! After the first index was created, the query that used it sped up by an embarrassing 20 seconds. I'm ashamed that I didn't create these indexes sooner.
I'm definitely no database administrator, but my suggestion would be to create a two-column index for each join that you perform in your application. One column would contain the primary key of the table that you're indexing, and the other column would be the foreign key in that same table.
For instance, to create an index on a table of users that you join to a table of accounts via a foreign key in the users table, you'd write a MySQL index like so:
CREATE INDEX users_accounts ON users (userID, accountID)
Do this for each of your joins and your database should be nice and speedy for a good, long while.