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.
-
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– Adrian Cornish2011年11月26日 01:31:35 +00:00Commented Nov 26, 2011 at 1:31
-
yeah edited my questionTasostheGreat– TasostheGreat2011年11月26日 01:36:51 +00:00Commented Nov 26, 2011 at 1:36
-
please use glorify \G for the schema and explain plan result, it should be more readableajreal– ajreal2011年11月26日 02:08:01 +00:00Commented 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 choosesAdrian Cornish– Adrian Cornish2011年11月26日 02:11:09 +00:00Commented Nov 26, 2011 at 2:11
-
@ajreal what is glorify?TasostheGreat– TasostheGreat2011年11月26日 02:14:18 +00:00Commented Nov 26, 2011 at 2:14
3 Answers 3
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
-
So? Where did I say it does? What the optimizer chooses is up to it? The index still works.Adrian Cornish– Adrian Cornish2011年11月26日 01:55:36 +00:00Commented 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– Adrian Cornish2011年11月26日 02:10:25 +00:00Commented 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– Adrian Cornish2011年11月26日 02:15:53 +00:00Commented Nov 26, 2011 at 2:15
-
let us continue this discussion in chatAdrian Cornish– Adrian Cornish2011年11月26日 02:21:58 +00:00Commented 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– Adrian Cornish2011年11月26日 02:37:05 +00:00Commented Nov 26, 2011 at 2:37
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.
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.