Question

Suppose I have a table events {id, userid, create_time, country, type, page, browser}

I have indexes on all the columns. If I do a query

select count(*) from events where id > ? and id < ? and userid>? and userid<? and create_time>? and create_time<? and browser=? and country=? and page=?

I have following questions:

  1. Will all my indices be used? If not, How to achieve that.
  2. Will it be better to have multiple column index?
  3. If I have a multiple column index on (id,userid,page), will it be used? If so will other indexes will also be used?
  4. If I have a multiple column index including all the columns but my query does not include all columns, then will that index be used?
Was it helpful?

Solution

Q: Will all my indices be used?

A: Very unlikely. It's more likely that MySQL will choose a single index, one that has the highest selectivity (eliminates the most rows), and then access the data pages from the index reference.

It's possible that MySQL would do an index merge operation, but that would be the rare exception. You'd really need to do an EXPLAIN to see if that's happening, and do some work to develop a case in which MySQL sees that as the optimal plan. (Someone has likely done the work, and has such a test case.)

Q: If not, How to achieve that.

A: You don't want to achieve that. What you want MySQL to do is generate an optimal plan. An index merge plan is most likely NOT the optimal plan for your query. Such an operation requires MySQL to "match" all of those indexes together, and that's a lot of heavy lifting to do.

Q: Will it be better to have multiple column index?

A: Yes. The best possible index for your particular query is a covering index, one that includes ALL the columns referenced in your query. Typically, you would want the column with the most selectivity and highest cardinality first. Your query appears to be doing range scans rather than equality tests, you'd want the column with the narrowest range of values in your predicate, compared to the entire set of values for the column, first in the index.

Q: If I have a multiple column index on (id,userid,page), will it be used?

A: Possibly. You have range scan predicates on two of the leading columns in that index, so it definitely looks like a candidate. If those are the only columns referenced in your query, then it makes it much more likely that index will be used.

There seems to be a malformed reference to create_time in your query text. It looks like you meant to have some sort of predicate on that column. If that's the case, then an index on (id, userid, create_time) would be a better candidate, because then the query could be satisfied from the index without referencing the data pages.

On the other hand, a full scan of the data pages might be a more optimal plan.

Q: If so will other indexes will also be used?

A: Very unlikely. The idea that MySQL will use "multiple" indexes on a table is a common misconception about how MySQL uses indexes. It's not out of the question, but it's very unlikely that an INDEX MERGE operation is the optimal plan.

Q: If I have a multiple column index including all the columns but my query does not include all columns, then will that index be used?

A: It's possible. If MySQL determines using that index is the optimal plan, then it will be used. The more likely index to be used (if available) would be a covering index that contains only the columns referenced in your query.

OTHER TIPS

Will all my indices be used?

No. Only one index will be used. You can see this in the output of EXPLAIN.

Will it be better to have multiple column index?

If you have equality constraints, yes. But it doesn't appear to be the case in your query. It will also be good to have a covering index - that is an index that contains all the values that your query needs.

If I have a multiple column index on (id,userid,page), will it be used?

Probably but I'd suggest adding create_time as that would make it a covering index. You don't need page in the index because it is not used in your query.

If I have a multiple column index including all the columns but my query does not include all columns, then will that index be used?

It depends on the order of the columns. If the query wants to use an index on create_time then it could use an index on (create_time, country) instead. But an index on (country, create_time) wouldn't help.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top