MySQL如何在哪里使用索引功能?

时间:2014-07-30 15:22:10

标签: mysql indexing

mysql如何在此查询中使用ts索引? ( EXTRA:使用where;使用索引

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 |

架构:

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小提琴链接:http://sqlfiddle.com/#!9/6aa3d/8

MySQL使用索引。为什么以及如何?

您能否提供描述此功能的MySQL文档页面?

2 个答案:

答案 0 :(得分:2)

MySQL中的BTREE索引(大多数索引都是)有两个目的:它可以用于根据特定密钥随机和/或顺序访问表的数据。如果它恰好包含查询所需的所有列,则索引还可用于满足查询。在您的情况下,MySQL将您的索引用于后一目的,而不是前者。

您已经显示的查询可以完全满足您定义的索引。这称为覆盖索引。这恰好是一个微不足道的案例,因为表中只有一列并且它已被索引。请查看POSSIBLE_KEYS结果集中的explain,注意没有结果。

这有点令人困惑。 MySQL正在使用索引来满足查询,因为它需要的所有列都在索引中。但是,它不使用键值访问索引。相反,它必须扫描整个事情。

通过使用密钥随机访问索引,不能满足将函数应用于列名的查询。在您的示例中,WHERE子句的格式为

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

如果你将这种不平等重塑为

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

MySQL将使用密钥进行搜索。它可以这样做,因为它将该表达式的右侧转换为常量,然后使用该常量随机访问第一个符合条件的值的索引。这称为索引范围扫描。

一些参考文献:http://planet.mysql.com/entry/?id=661727

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

答案 1 :(得分:0)

这与:

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

可以愉快地使用索引。