11

I have set up my table with an index only on done_status(done_status = INT):

enter image description here

When I use:

EXPLAIN SELECT * FROM reminder  WHERE done_status=2

I get this back:

id  select_type  table     type  possible_keys  key  key_len  ref  rows  Extra
1   SIMPLE       reminder  ALL   done_status    NULL NULL     NULL 5     Using where

But when I issue this command:

EXPLAIN SELECT * FROM reminder  WHERE done_status=1

I get the following returned:

id  select_type  table     type  possible_keys  key          key_len  ref   rows  Extra
1   SIMPLE       reminder  ref   done_status    done_status  4        const 2   

The EXPLAIN shows me that it uses 5 rows, the second time 2 rows.

I don't think the index is used, if I understood it right first time it should give me 3 rows. What do I do wrong?

SHOW INDEX FROM reminder:

Table    Non_unique  Key_name     Seq_in_index  Column_name  Collation  Cardinality  Sub_part  Packed  Null  Index_type  Comment  Index_comment
reminder 1           done_status  1             done_status  A          5            NULL      NULL          BTREE

explain extended:

id  select_type  table     type  possible_keys  key          key_len  ref    rows  filtered  Extra
1   SIMPLE       reminder  ref   done_status    done_status  4        const  2     100.00

show warnings didn't show anything of interest.

7
  • Trust me the index works. But I cant see anything easily in your screen shot - can you do a "show index from yourtable"
    – Adrian Cornish
    Nov 26, 2011 at 1:31
  • yeah edited my question
    – TasostheGreat
    Nov 26, 2011 at 1:36
  • please use glorify \G for the schema and explain plan result, it should be more readable
    – ajreal
    Nov 26, 2011 at 2:08
  • Out of interest can you repeat with a "explain extended" and a "show warnings" this will show the actual SQL mysql chooses
    – Adrian Cornish
    Nov 26, 2011 at 2:11
  • @ajreal what is glorify?
    – TasostheGreat
    Nov 26, 2011 at 2:14

3 Answers 3

5

You misunderstand what the 'rows' field is. It is the number of rows that mysql estimates it shall need to read to satisfy your query. This value can be quite inaccurate. It does not mean this is the number of rows in the result - or the actual number of rows read by mysql

5
  • So? Where did I say it does? What the optimizer chooses is up to it? The index still works.
    – Adrian Cornish
    Nov 26, 2011 at 1:55
  • @ajreal It does not mean the index is broken though. Just the optimizer choose (in its mind) the most efficient way to query the data. I assumed the OP was expecting the rows column in the EXPLAIN to be exact. It does not mean the index is broken - just that mysql choose not to use it (probably).
    – Adrian Cornish
    Nov 26, 2011 at 2:10
  • 1
    @ajreal: I am missing something in your points. The rows column of an explain has nothing to do with indexes right? Mysql choose not to use the index (maybe all the data is in a single page). Not sure I am understanding your point? Query optimization on a 5 row table is going to produce some 'odd' results because it pretty much does not matter how you optimize.
    – Adrian Cornish
    Nov 26, 2011 at 2:15
  • let us continue this discussion in chat
    – Adrian Cornish
    Nov 26, 2011 at 2:21
  • In this case who cares what index the optimizer chooses? There is nothing wrong with the index itself, because the optimizer felt like it did not need it - what does it matter?
    – Adrian Cornish
    Nov 26, 2011 at 2:37
3

The first execution plain is not make use of index for sure,
it could be the information_schema.statistics on the index does not catch up with the data after some write operations, or the table is not been accessed for a long time.

as explain here :- From where does the MySQL Query Optimizer read index statistics?

for the second execution plan, it seems information_schema.statistics already catch up and fix the NULL cardinality issue.

Therefore, is execute the query according to the index optimizer.

For table with small rows, it does not matter much.
But data will growth, developer should always do a check on this,
and perform the necessary analyze table when encounter cardinality is null on the index.

1

The first execution plan is not using an index.

From MySQL Reference Website:

Sometimes MySQL does not use an index, even if one is available. One circumstance under which this occurs is when the optimizer estimates that using the index would require MySQL to access a very large percentage of the rows in the table. (In this case, a table scan is likely to be much faster because it requires fewer seeks.) However, if such a query uses LIMIT to retrieve only some of the rows, MySQL uses an index anyway, because it can much more quickly find the few rows to return in the result.

If your table has only 5 rows and your query selects 3 of them, then MySQL optimizer assumes that it is more efficient to scan the whole table.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.