Take the 2-minute tour ×

I have a table of items, each of it has an a_level, b_level, and an item_id. Any b_level is dedicated to only one a_level (example: b_level 14 is "child" of a_level 2 only)

Lets say we have million of items all of them are INSERTed once and then only SELECTs are requested.

If i SELECT an item based on item_id, then i need to index the item_id column. This will make the MySQL to look all millions of items, which is bad, since i already have the a_level and b_level information. So i guess if i SELECT an item based on a specific level and i have an index on that column, the MySQL will not have to look all millions of items, just the items with that particular level.

If i INDEX both on a_level, b_level (and of course item_id) and SELECT WHERE a_level= b_level= item_id= will it be bad? I guess only INDEX on b_level and item_id and SELECT WHERE b_level= AND item_id= will be enough/the best solution?

So, since i have a_level and b_level (which any b_level as i said is "child" of only one a_level) what will be the most efficient SELECT and INDEXes created for picking up an item?

share|improve this question

2 Answers 2

up vote 1 down vote accepted

You can certainly index every column. If you do, MySQL will use index merge optimization to apply many indexes to a single query. However, for more efficiency, you might want to use composite indexes (single index on multiple columns). MySQL composite indexes are used in optimization by following the left-prefix rule. If the SELECT statement is restricted by terms that are included in a left-prefix of an index, that index is used. For example, if you have

SELECT * FROM t WHERE a_level = 1 AND b_level = 2

then the appropriate index would have to include a_level or b_level as the first columns. In other words, an index for (a_level, b_level) could index queries such as

SELECT * FROM t WHERE a_level = 1
SELECT * FROM t WHERE a_level = 1 AND b_level = 2

but not

SELECT * FROM t WHERE b_level = 2

because b_level is not a left-prefix of the index.

You'd probably first want to benchmark which of the selects you're performing most often and create indexes based on that, as long as they follow the left-prefix rule. You might want to use several indexes for a few of the different SELECT queries in order to keep from blanketing the entire table. It's not easy to perfectly answer this question without knowing the data and queries exactly.

However, if you're sure you're never going to write into the table again, you might as well cover the entire thing with an index, if space is not an issue.

share|improve this answer

if you do select by a column or set of colums frequently, then index that column or set of columns. Indexes don't look all millions of items, that's why they're indexes (without an index, it would indeed look all millions of items)

share|improve this answer
should i INDEX both a_level and b_level and SELECT using both of them (and item_id), or only INDEX b_level and SELECT using b_level (and item_id)? (both cases also INDEX at item_id) –  Sharky Oct 12 '11 at 18:38
if your select is like select * from mytable where item_id = 2323 then you just need index by item_id. If you don't know the item_id but need to rely on other columns, then index those. Adding a bit, say you want to know the item ids 'children' of a_level 'X', then you would index by a_level. The idea is to index whatever is in the 'where' part if you use it frequently –  Rodolfo Oct 12 '11 at 18:39

Your Answer


