【发布时间】:2017-10-04 01:47:28
【问题描述】:
我有以下两个 MySQL/MariaDB 表:
CREATE TABLE requests (
request_id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
unix_timestamp DOUBLE NOT NULL,
[...]
INDEX unix_timestamp_index (unix_timestamp)
);
CREATE TABLE served_objects (
request_id BIGINT UNSIGNED NOT NULL,
object_name VARCHAR(255) NOT NULL,
[...]
FOREIGN KEY (request_id) REFERENCES requests (request_id)
);
每个表中有几百万列。每个请求有零个或多个服务对象。我有一个通过加入这两个表来提供完整的服务对象视图的视图:
CREATE VIEW served_objects_view AS
SELECT
r.request_id AS request_id,
unix_timestamp,
object_name
FROM requests r
RIGHT JOIN served_objects so ON r.request_id=so.request_id;
到目前为止,这一切似乎都很简单。但是当我像这样做一个简单的选择时:
SELECT * FROM served_objects_view ORDER BY unix_timestamp LIMIT 5;
需要整整一分钟或更长时间。它显然没有使用索引。我尝试了许多不同的方法,包括翻转事物并使用 LEFT 或 INNER 连接,但无济于事。
这是此 SELECT 的 EXPLAIN 的输出:
+------+-------------+-------+--------+---------------+---------+---------+------------------+---------+---------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+-------+--------+---------------+---------+---------+------------------+---------+---------------------------------+
| 1 | SIMPLE | so | ALL | NULL | NULL | NULL | NULL | 5196526 | Using temporary; Using filesort |
| 1 | SIMPLE | r | eq_ref | PRIMARY | PRIMARY | 8 | db.so.request_id | 1 | |
+------+-------------+-------+--------+---------------+---------+---------+------------------+---------+---------------------------------+
这里有什么基本的东西阻止索引被使用吗?我知道它需要使用临时表来满足视图,并且这会干扰使用索引的能力。但我希望存在一些技巧,允许我从视图中选择,同时尊重请求表中的索引。
【问题讨论】:
-
尝试添加一个
unix_timestamp, object_name复合索引,这将是一个覆盖索引。
标签: mysql select join indexing