Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6812497
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 26, 20262026-05-26T20:27:23+00:00 2026-05-26T20:27:23+00:00

Why does Mysql optimizer choose the secondary index when doing a ‘select * from

  • 0

Why does Mysql optimizer choose the secondary index when doing a ‘select * from lookup’ with no order by clause.

Is it just a fluke or is this a behind the scenes optimization that assumes since you added a secondary index its more important than the primary key.

I would expect the results to be ordered by primary key as a scan of all the leaf nodes can provide all the data necessary to answer this query.

To reproduce I create a simple key/value pair table (note not auto_increment)

create table lookup (
id int not null,
primary key (id),
name varchar(25),
unique k_name (name)
) engine=innodb;

Insert some data in random non-alphabetical order

insert into lookup values(1, "Zebra"),(2, "Aardvark"),(3, "Fish"),(4,"Dog"),(5,"Cat"),(6,"Mouse");

Query the data (this is where I would expect the data to be returned in order of primary key)

mysql> select * from lookup;
+----+----------+
| id | name     |
+----+----------+
|  2 | Aardvark |
|  5 | Cat      |
|  4 | Dog      |
|  3 | Fish     |
|  6 | Mouse    |
|  1 | Zebra    |
+----+----------+
6 rows in set (0.00 sec)

Where as it is not – it appears that a scan of the k_name leaf nodes has been done. Shown here

mysql> explain select * from lookup;
+----+-------------+--------+-------+---------------+--------+---------+------+------+-------------+
| id | select_type | table  | type  | possible_keys | key    | key_len | ref  | rows | Extra       |
+----+-------------+--------+-------+---------------+--------+---------+------+------+-------------+
|  1 | SIMPLE      | lookup | index | NULL          | k_name | 28      | NULL |    6 | Using index |
+----+-------------+--------+-------+---------------+--------+---------+------+------+-------------+
1 row in set (0.00 sec)

To me this says Mysql is using k_name as a covering index to return the data. If I drop the k_name index then data is returned in primary key order. If I add another un-indexed column data is returned in primary key order.

Some basic information about my setup.

mysql> show table status like 'lookup'\G
*************************** 1. row ***************************
           Name: lookup
         Engine: InnoDB
        Version: 10
     Row_format: Compact
           Rows: 6
 Avg_row_length: 2730
    Data_length: 16384
Max_data_length: 0
   Index_length: 16384
      Data_free: 0
 Auto_increment: NULL
    Create_time: 2011-11-15 10:42:35
    Update_time: NULL
     Check_time: NULL
      Collation: latin1_swedish_ci
       Checksum: NULL
 Create_options:
        Comment:
1 row in set (0.00 sec)

 mysql> select version();
 +------------+
 | version()  |
 +------------+
 | 5.5.15-log |
 +------------+
 1 row in set (0.00 sec)
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-26T20:27:23+00:00Added an answer on May 26, 2026 at 8:27 pm

    In reality, the clustered index (aka gen_clust_index) is populated in an order that has no rhyme or reason other than in rowid order. it is virtually impossible to order the rowids in id order.

    In InnoDB, the records in nonclustered indexes (also called secondary indexes) contain the primary key columns for the row that are not in the secondary index. InnoDB uses this primary key value to search for the row in the clustered index.

    The secondary index governs order. However, each secondary index entry has a primary key entry to the correct row. Also, think of the covering index scenario you mentioned for k_name.

    Now, let’s switch gears for a moment and discusss the PRIMARY KEY and k_name:

    QUESTION : Whose has more columns requested by your original query, the Primary Key or k_name ?

    ANSWER : k_name, because it has both name and id in it (id being internal because it is the PRIMARY KEY). The covering index k_name fulfills the query better than the primary key.

    Now if the query was SELECT * FROM ORDER BY id, your EXPLAIN PLAN should look like this:

    mysql> explain select * from lookup order by id;
    +----+-------------+--------+-------+---------------+---------+---------+------+------+-------+
    | id | select_type | table  | type  | possible_keys | key     | key_len | ref  | rows | Extra |
    +----+-------------+--------+-------+---------------+---------+---------+------+------+-------+
    |  1 | SIMPLE      | lookup | index | NULL          | PRIMARY | 4       | NULL |    6 |       |
    +----+-------------+--------+-------+---------------+---------+---------+------+------+-------+
    
    1 row in set (0.00 sec)
    

    Without specfiying order, the MySQL Query Optimizer picks the index that best fulfills your query. Of course, k_name has the unfair advantage because

    • every column in the table is individually indexed
    • every column in the table is a Candidate Key
    • k_name IS NOT A SECONDARY INDEX because it is a Candidate Key just like the PRIMARY KEY.
    • user-defined clustered indexes cannot have the row order altered once established

    You cannot manipulate the order of the rows at all. Here is proof of that:

    mysql> alter table lookup order by name;
    Query OK, 6 rows affected, 1 warning (0.23 sec)
    Records: 6  Duplicates: 0  Warnings: 1
    
    mysql> show warnings;
    +---------+------+-----------------------------------------------------------------------------------+
    | Level   | Code | Message                                                                           |
    +---------+------+-----------------------------------------------------------------------------------+
    | Warning | 1105 | ORDER BY ignored as there is a user-defined clustered index in the table 'lookup' |
    +---------+------+-----------------------------------------------------------------------------------+
    1 row in set (0.00 sec)
    
    mysql> alter table lookup order by id;
    Query OK, 6 rows affected, 1 warning (0.19 sec)
    Records: 6  Duplicates: 0  Warnings: 1
    
    mysql> show warnings;
    +---------+------+-----------------------------------------------------------------------------------+
    | Level   | Code | Message                                                                           |
    +---------+------+-----------------------------------------------------------------------------------+
    | Warning | 1105 | ORDER BY ignored as there is a user-defined clustered index in the table 'lookup' |
    +---------+------+-----------------------------------------------------------------------------------+
    1 row in set (0.00 sec)
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Does MySQL index foreign key columns automatically?
when $query = 'SELECT * FROM users'; and there are multiple columns/rows, does mysql_fetch_assoc($result)
In mysql, does the order of the WHERE clauses affect the time that it
I have the following MySql query: select t1.* from Table1 t1 inner join Table2
Does MySQL support MSDTC?
Does MySQL come with a built-in automatic failover? Or, are there load-balancers out there
Does mysql provide a mechanism for storing and retrieving encrypted data? I don't mean
What does MYSQL mean in the following code. require_once (MYSQL);
Does the MySQL command : FLUSH TABLES; flush every table in the current database,
Why does the MySQL year type limit the range of allowable years between 1901

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.