Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MYSQL Index on TIMESTAMP field not using index for range query

Tags:

indexing

mysql

I have the following row in a mysql table

+--------------------------------+----------------------+------+-----+---------+----------------+
| Field                          | Type                 | Null | Key | Default | Extra          |
+--------------------------------+----------------------+------+-----+---------+----------------+
| created_at                     | timestamp            | YES  | MUL | NULL    |                |

The following index exists on the field

*************************** 6. row ***************************
        Table: My_Table
   Non_unique: 1
     Key_name: IDX_My_Table_CREATED_AT
 Seq_in_index: 1
  Column_name: created_at
    Collation: A
  Cardinality: 273809
     Sub_part: NULL
       Packed: NULL
         Null: YES
   Index_type: BTREE
      Comment: 
Index_comment:

I am trying to optimize the following query to use the IDX_My_Table_CREATED_AT index for the range condition

SELECT * FROM My_Table as main_table  WHERE ((main_table.created_at >= '2013-07-01 05:00:00') AND (main_table.created_at <= '2013-11-09 05:59:59'))\G

When I use EXPLAIN on the select query, I get the following:

+----+-------------+------------+------+---------------------------------+------+---------+------+--------+-------------+
| id | select_type | table      | type | possible_keys                   | key  | key_len | ref  | rows   | Extra       |
+----+-------------+------------+------+---------------------------------+------+---------+------+--------+-------------+
|  1 | SIMPLE      | main_table | ALL  | IDX_My_Table_CREATED_AT         | NULL | NULL    | NULL | 273809 | Using where |
+----+-------------+------------+------+---------------------------------+------+---------+------+--------+-------------+

The issue is that the IDX_My_Table_CREATED_AT index is not being used for this range condition, even though it is a BTREE index and therefore should be applicable to the query.

Strangely, if I attempt a single value lookup on the column, the index is used.

EXPLAIN SELECT * FROM My_Table as main_table  WHERE (main_table.created_at = '2013-07-01 05:00:00');
+----+-------------+------------+------+---------------------------------+---------------------------------+---------+-------+------+-------------+
| id | select_type | table      | type | possible_keys                 | key                           | key_len | ref   | rows | Extra       |
+----+-------------+------------+------+---------------------------------+---------------------------------+---------+-------+------+-------------+
|  1 | SIMPLE      | main_table | ref  | IDX_My_Table_CREATED_AT index | IDX_My_Table_CREATED_AT index | 5       | const |    1 | Using where |
+----+-------------+------------+------+---------------------------------+---------------------------------+---------+-------+------+-------------+

Why isn't the index being used for the range condition? I have tried changing the query to use BETWEEN but that didn't change anything.

like image 638
Sean Avatar asked Dec 24 '13 17:12

Sean


People also ask

Can timestamp be indexed?

Yep, it absolutely is recommended and normal to index the timestamp columns when you query on them! I index my timestamps when I know I will query/sort by that column often.

Why MySQL does not pick correct index for few queries?

Solution #1: OPTIMIZE If MySQL got it wrong, it may be because the table was frequently changed. This affects the statistics. If we can spare the time (table is locked during that time), we could help out by rebuilding the table.

Why index is not used in MySQL?

The Benefits and Drawbacks of Using Indexes in MySQLIndexes consume disk space. Indexes degrade the performance of INSERT, UPDATE and DELETE queries – when data is updated, the index needs to be updated together with it. MySQL does not protect you from using multiple types of indexes at the same time.

Does MySQL use index for in query?

Introduction to MySQL indexesAn index is a data structure used to locate data without scanning all the rows in a table for a given query. Indexes help retrieve data faster. Indexes are not visible to the users. They help speed up queries that require a search.


1 Answers

The answer is simple..

The MySQL optimizer is cost based and the optimizer calculated that an full table scan was the best way (cheapest) to fetch the records.

Because the range needed looks like to be the complete table looking into the rows (EXPLAIN) and Cardinality. these numbers are equal.

If the MySQL optimizer did use an index the relative cost would be much higher because of the random reads (slow) what are necessary to look up the records

motto off the story an FULL TABLE SCAN in this case is not the end off the world... just accept it..

like image 60
Raymond Nijland Avatar answered Sep 22 '22 20:09

Raymond Nijland