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文档页面?
答案 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'));
可以愉快地使用索引。