1

How can mysql use ts index in this query? (EXTRA: Using where; Using index)

EXPLAIN SELECT * FROM times
WHERE UNIX_TIMESTAMP(CONVERT_TZ(FROM_UNIXTIME(ts), 'GMT', 'EET')) > 10000;


| ID | SELECT_TYPE | TABLE |  TYPE | POSSIBLE_KEYS |     KEY | KEY_LEN |    REF | ROWS |                    EXTRA |
|----|-------------|-------|-------|---------------|---------|---------|--------|------|--------------------------|
|  1 |      SIMPLE | times | index |        (null) | PRIMARY |       4 | (null) |   10 | Using where; Using index |

The schema:

CREATE TABLE times(
    ts int(11) NOT NULL COMMENT 'timestamp',
    PRIMARY KEY (ts)
);

INSERT INTO times VALUES (0), (1000), (5000), (10000), (15000),
(20000), (600000), (7000000), (80000000), (900000000);

SQL fiddle link: http://sqlfiddle.com/#!9/6aa3d/8

MySQL uses index. Why and how?

Could you provide me with MySQL documentation page describing this feature?

4
  • you can't use indexes. you're doing various calculations/changes to the stored data, and the indexes apply ONLY to the stored data. there's no indexes on the converted values at all.
    – Marc B
    Commented Jul 30, 2014 at 15:24
  • @MarcB But EXPLAIN writes that index is used.
    – Dmitry
    Commented Jul 30, 2014 at 15:25
  • Do the conversion of the right side of the > operator
    – VMai
    Commented Jul 30, 2014 at 15:27
  • @VMai I know the rules. But why is the index used?
    – Dmitry
    Commented Jul 30, 2014 at 15:30

2 Answers 2

5

A BTREE index in MySQL (which most indexes are) serves two purposes: it can be used to randomly and/or sequentially access the data of a table based on a particular key. The index can also be used to satisfy a query if it happens to contain all the columns the query requires. In your case, MySQL uses your index for the latter purpose but not the former.

The query you have shown can be entirely satisfied from the index you have defined. That's called a covering index. This happens to be be a trivial case, because there's only one column in the table and it is indexed. Take a look at POSSIBLE_KEYS in your explain resultset, and notice that there are none.

This is a little confusing. MySQL is using the index to satisfy the query because all the columns it requires are in the index. However, it is not accessing the index using a key value. Instead, it has to scan the whole thing.

No query which applies a function to a column name can be satisfied by random-accessing an index using a key. In your sample case your WHERE clause has the form

WHERE f(g(h(column))) > value

If you recast that inequality as

WHERE column > H(G(F(value)))

MySQL will employ the key to do its search. It can do this because it converts the right-hand-side of that expression to a constant, then uses the constant to random-access the index at the first eligible value. That's called an index range scan.

Some references: http://planet.mysql.com/entry/?id=661727

http://www.mysqlperformanceblog.com/2006/11/23/covering-index-and-prefix-indexes/

3
  • Actually I have this incomprehension with a table with 50+ fields, ~10 indexes and some millions of rows.
    – Dmitry
    Commented Jul 30, 2014 at 15:34
  • @DmitryR You did a good job of reducing your question to a sample case. I suggest you study covering indexes and range scans, because this all can be quite complex in the real world. I have included a couple of references.
    – O. Jones
    Commented Jul 30, 2014 at 15:40
  • Thank you. Your answer is very informative and full.
    – Dmitry
    Commented Jul 30, 2014 at 17:24
0

This is the same as:

SELECT * 
  FROM times
 WHERE ts > UNIX_TIMESTAMP(CONVERT_TZ(FROM_UNIXTIME(10000), 'EET', 'GMT'));

Which can use the index happily.

3
  • I know. It was just an example of code, that uses index, and I don't know why.
    – Dmitry
    Commented Jul 30, 2014 at 15:29
  • My query (that's incorrect by the reason you had described) also uses index. And I'm wondering, why.
    – Dmitry
    Commented Jul 30, 2014 at 15:38
  • @DmitryR ah ok, see Ollie's answer I guess.
    – Arth
    Commented Jul 30, 2014 at 15:42

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.