1

I have a table with two columns, batch_id and study_id. There are indexes on both columns. I want to get a random row back from MySQL.

I originally wrote:

SELECT * FROM alt_join_batch_study ORDER BY RAND() LIMIT 1

but that proved slow. Here's the explain.

id    select_type    table    type    possible_keys    key    key_len    ref    rows    Extra
1    SIMPLE    alt_join_batch_study    ALL    NULL    NULL    NULL    NULL    172235    Using temporary; Using filesort

I was surprised it wasn't using any indexes. I tried this:

SELECT batch_id, study_id FROM alt_join_batch_study ORDER BY RAND() LIMIT 1

and Lo! it was faster. And the explain shows the use of the index.

id    select_type    table    type    possible_keys    key    key_len    ref    rows    Extra
1    SIMPLE    alt_join_batch_study    index    NULL    study_id    4    NULL    172235    Using index; Using temporary; Using filesort

Why wouldn't MySQL find the index when I do SELECT * ...?

Alan C.
  • 347
  • 1
  • 11

2 Answers2

2

If the table is InnoDB, here is what's happening:

The query optimizer sees SELECT * and does this

  • Sees all columns are included in the SELECT list
  • Uses the clustered index since all columns are included

The query optimizer sees SELECT batch_id, study_id and does this

  • Sees SELECT list has two columns, not all columns
  • Sees the study_id index (and other indexes)
  • Chooses the study_id index
  • Retrieves batch_id using PRIMARY KEY attached to study_id index entry

Why would this happen at all? The Query Optimizer is kinda picky

Sometimes, it can go the other way

The key to your question is that the Query Optimizer does not view the two queries as almost identical. To the query optimizer, they are completely different in appearance and in its treatment.

RolandoMySQLDBA
  • 185,223
  • 33
  • 326
  • 536
0

It will run through all rows. However, it might be able to run through the "rows" in some index rather than running through the entire dataset.

See my blog with 8 techniques for speeding up ORDER BY RAND()

Your EXPLAIN may lead to a 9th. :)

Rick James
  • 80,479
  • 5
  • 52
  • 119