views:

757

answers:

6

I'm trying to fine-tune my MySQL server so i check my settings, analyzing slow-query log, simplify my queries if possible.

Sometimes enough if i indexing correctly sometimes not. I've read somewhere (pls correct me if this is stupidity) more indexes than i needed make the same effect like i haven't any of them.

How many indexes are enough? You can say it depends on hundreds of factors but i'm curious about how can i clean up my mysql-slow.log enough to reduce server load.

Furthermore i saw some "interesting" log entries like this:

# Query_time: 0  Lock_time: 0  Rows_sent: 22  Rows_examined: 44
SELECT * FROM `categories` ORDER BY `orderid` ASC;

The table in question contains exactly 22 rows, index set in orderid. Why showing up this query in the log after all? Why examine 44 rows if it only contains 22?

+2  A: 

There's no magic number for the "best" number of indexes. The basic rule is this: add indexes for queries that are used often and/or need to run quickly.

Having "too many" indexes shouldn't slow down queries, but it each index added adds a small amount of time to add/update items in the db (since it modifies the indices as well), and a small amount of space. However, if you're just adding indexes as required, this is probably not a big concern.

Beska
+6  A: 

As a general rule, you should have indexes on all primary keys (you don't have a choice in that), all foreign keys, and any other fields you commonly use to fetch rows.

For example, if I commonly look up users by username, I would have that indexed, even if user ID was the primary key.

R. Bemrose
+4  A: 

How many indexes depends entirely on the queries your running, what kinds of joins are being done (if any), the kind of data stored in the table and how big the tables are (as well as many other factors). There's really no exact science to it. The greatest tool in your arsenal for figuring out how to optimize a query is explain. Using explain you can find out what kind of joins are being down, what possible keys could be used and which key (if any) was used as well as how many rows were examined for each table in the join.

Using this information you can decide how to key your tables and/or modify your queries to make them more efficient. The syntax for explain is very simple.

EXPLAIN SELECT * FROM `categories` ORDER BY `orderid` ASC;

Note, explain does not actually run the query. So if you're using this to debug a query that takes 5 minutes to run, explain will still be very fast.

You do need to be careful when adding indexes though as they do cause inserts and updates to go slower and on very large tables this performance hit can become noticeable. Especially if that same table is used for a lot of reads. While adding a lot of indexes generally won't kill the performance of a query, you should still only add them as yo

Steven Surowiec
Great comment, thank you!
fabrik
+2  A: 

An index can speed up a SELECT query, but it will slow down INSERT/UPDATE/DELETE queries because they need to update the index as well, not just the row.

This is just personal opinion (I've got no facts to back it up), but I think that if there is a query that is taking a long time and an index would speed it up - go for it! "Too many" indexes would be if you added indexes that didn't do any good (e.g. there were no queries it would speed up). For example, a silly thing to do would be to place an index on every column "just because".

Vilx-
"a silly thing to do would be to place an index on every column "just because"" - This is totally ok but i'd like to eliminate as much slow-log entries as i can. Otherwise thanks for the thoughts on INSERTs/UPDATEs/DELETEs!
fabrik
+4  A: 

The amount of indexing and the line of doing too much will depend on a lot of factors. On small tables like your "categories" table you usually don't want or need an index and it can actually hurt performance. The reason being is that it takes I/O (i.e. time) to read an index and then more I/O and time to retrieve the records associated with the matched rows. An exception being when you only query the columns contained within the index.

In your example you are retrieving all the columns and with only 22 rows and it may be faster to just do a table scan and sort those instead of using the index. The optimizer may/should be doing this and ignoring the index. If that is the case, then the index is just taking up space with no benefit. If your "categories" table is accessed often, you may want to consider pinning it into memory so the db server keeps it accessible without having to goto the disk all the time.

When adding indexes you need to balance out disk space, query performance, and the performance of updating and inserting into the tables. You can get away with more indexes on tables that are static and don't change much as opposed to tables with millions of updates a day. You'll start feeling the affects of index maintenance at that point. What is acceptable in your environment though is and can only be determined by you and your organization.

When doing your analysis, be sure to generate/update your table and index statistics so that you can be assured of accurate calculations.

RC
Thank you! This was the most clear and helpful answer for me!
fabrik
A: 

Also keep in mind that MySQL will use a maximum of one index per select statement (although if you are using a join, it can also use one for each join). So indexing just because is a waste of disk space and will slow the database down on writes. If you commonly use a where statement on two columns, do one index containing both of those columns, it will be significantly faster than indexing just one alone.

scotts