mysql - MySQL如何在where函数中使用索引?

标签 mysql indexing

mysql如何在此查询中使用ts索引? (额外:使用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 fiddle链接:http://sqlfiddle.com/#!9/6aa3d/8

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

您能为我提供描述此功能的 MySQL 文档页面吗?

最佳答案

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

您所显示的查询可以完全通过您定义的索引来满足。这称为覆盖索引。这恰好是一个微不足道的情况,因为表中只有一列并且已建立索引。查看 explain 结果集中的 POSSIBLE_KEYS,你会发现没有。

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

使用键随机访问索引无法满足将函数应用于列名的查询。在您的示例案例中,您的 WHERE 子句具有以下形式

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

如果你将这种不平等重新表述为

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

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

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

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

关于mysql - MySQL如何在where函数中使用索引?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25040704/

相关文章:

python - 提取一个列表,其值的位置由 Pandas DataFrame 中另一列中的值指示

mySQL 非聚集索引 + 非索引字段是否仍然比 2 x 非索引字段快?

MySQL 5.7 与 5.6 : Index usage wrong at first, 但 "automagically"几周后修复

MySQL:选择上次修改时具有一个属性但过去没有其他属性的项目

php - 将 SUM 与基于公式的行文本内容结合使用,全部与 WHERE、JOIN、ORDER 一起使用

php - 合并共享相同 id 的数组

mysql - sql查询减号运算

database - postgres 数据库中文本字段的合适索引是什么?

css - CSS 内容和背景 URL 图像的 SEO

php - 选择更新