简体   繁体   中英

mysql index seems to fail in large table

I use a large (>100 million rows) table with the following create:

 data_values | CREATE TABLE `data_values` (
  `T` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
  `ID` varchar(32) NOT NULL,
  `VAL` float DEFAULT NULL,
  PRIMARY KEY (`T`,`ID`),
  KEY `IX_d` (`ID`),
  KEY `IX_T` (`T`)
) ENGINE=InnoDB DEFAULT CHARSET=greek PACK_KEYS=1 ROW_FORMAT=DYNAMIC |

My queries are of the following form:

select t,id,val from data_values where t between "2013-01-11 02:47:02" and "2013-01-12 04:59:02" and id="815";

My problem is that sometimes the index is used (and the answer comes pretty fast), and sometimes it is not used (and the answer comes in 1-2 minutes), and I can't find any logic behind that. For example the following query is fast:

select t,id,val from data_values where t between "2013-01-11 02:47:02" and "2013-01-13 04:59:02" and id="815";

while the following query (which asks for less data, one day instead of two) is slow:

select t,id,val from data_values where t between "2013-01-11 02:47:02" and "2013-01-12 04:59:02" and id="815";

Explaining the queries:

explain select t,id,value from data_values where t between "2013-01-11 02:47:02" and "2013-01-13 04:59:02" and id="815";
| id | select_type | table                | type        | possible_keys
| key             | key_len | ref  | rows | Extra
          |
+----+-------------+----------------------+-------------+-----------------------
+-----------------+---------+------+------+-------------------------------------
----------+
|  1 | SIMPLE      | data_values           | index_merge | PRIMARY,IX_D,IX_T
| IX_D,PRIMARY     | 34,38  | NULL | 1033 | Using intersect(IX_D,PRIMARY); Us
ing where |
+----+-------------+----------------------+-------------+-----------------------
+-----------------+---------+------+------+-------------------------------------


explain select t,id,val from data_values where t between "2013-01-11 02:47:02" and "2013-01-12 04:59:02" and id="815";
+----+-------------+----------------------+------+-----------------------+------
---+---------+-------+--------+-------------+
| id | select_type | table                | type | possible_keys         | key
   | key_len | ref   | rows   | Extra       |
+----+-------------+----------------------+------+-----------------------+------
---+---------+-------+--------+-------------+
|  1 | SIMPLE      | data_values          | ref  | PRIMARY,IX_D,IX_T     | IX_D            | 34      | const | 143900 | Using where |
+----+-------------+----------------------+------+-----------------------+------
---+---------+-------+--------+-------------+

I don't understand how the first query, which is "broader" (asks for more data) uses the index and the second one does not. Searching stackoverflow I have found some answers regarding multiple-column indexes. But I already use one (my primary key),and in the correct order (in the queries, t variable is mentioned before the id). Another answer I have found concerns queries with OR (do separate queries and form a UNION) but my query uses AND.

I need advice on how I can speed up my queries,

thanks a lot.

You have an index on (t, id) .

You need an index on (id, t) for this kind of query, or even better, a "covering" index on (id, t, val) :

ALTER TABLE data_values
    DROP INDEX IX_T           -- the Primary Key is (t, id) so this index 
                              -- is rather redundant.
  , DROP INDEX IX_d           -- this was not redundant but it is now
                              -- (because of) 
  , ADD INDEX IX_ID_T_VAL     -- the new index
        (id, t, value) ;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM