如何使 mysql 派生 table 使用索引
how to make mysql derived table use index
MySQL 版本 5.6.33
我有两个 tables (files & details) 到内连接
table files,有一个名为 idx_record(record_id)[= 的索引16=]
table details,有一个名为 idx_end_org_record(end_at, org_id, record_id)
explain
SELECT
id as file_id,
record_id,
recording_path
FROM `files`
INNER JOIN
(
SELECT `details`.`record_id`
FROM `details`
WHERE `details`.`org_id` IN (6231, 6232, 6233, 6234)
AND (`details`.`end_at` BETWEEN '2017-05-31 16:00:00' AND '2017-06-13 16:00:00')
ORDER BY end_at desc
) as b
on `files`.record_id = b.record_id
WHERE (file_name IS NOT NULL )
LIMIT 30
输出如下
+----+-------------+--------------+-------+--------------------+--------------------+---------+------------------+---------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+--------------+-------+--------------------+--------------------+---------+------------------+---------+--------------------------+
| 1 | PRIMARY | <derived2> | ALL | NULL | NULL | NULL | NULL | 3844632 | Using where |
| 1 | PRIMARY | files | ref | idx_record | idx_record | 5 | b.record_id | 1 | Using where |
| 2 | DERIVED | details | range | idx_end_org_record | idx_end_org_record | 11 | NULL | 3844632 | Using where; Using index |
+----+-------------+--------------+-------+--------------------+--------------------+---------+------------------+---------+--------------------------+
如您所见,<derived2>
table 没有使用任何索引,这使得该查询几乎需要 1 秒才能完成。
感谢任何帮助!
此外,在查询中删除 WHERE (file_name IS NOT NULL )
没有任何区别。
而在 mysql 5.7 中,这个问题甚至不存在,但目前我正在尝试在 5.6 中解决这个问题。
我不明白子查询的意义所在。特别是,子查询中的 ORDER BY
是没有意义的。如果您将查询编写为两个 table 之间的直接连接,那么优化器应该能够利用连接列上的索引:
SELECT
id as file_id,
record_id,
recording_path
FROM files f
INNER JOIN details d
ON f.record_id = d.record_id AND
d.org_id IN (6231, 6232, 6233, 6234) AND
d.end_at BETWEEN '2017-05-31 16:00:00' AND '2017-06-13 16:00:00'
WHERE f.file_name IS NOT NULL
ORDER BY <some column> -- it doesn't make sense most of the time to use LIMIT
LIMIT 30 -- without ORDER BY
在 details
table 中的 record_id
、org_id
和 end_at
以及 file_name
中添加索引=17=] table,应该会给你一些性能改进。
MySQL 版本 5.6.33
我有两个 tables (files & details) 到内连接
table files,有一个名为 idx_record(record_id)[= 的索引16=]
table details,有一个名为 idx_end_org_record(end_at, org_id, record_id)
explain
SELECT
id as file_id,
record_id,
recording_path
FROM `files`
INNER JOIN
(
SELECT `details`.`record_id`
FROM `details`
WHERE `details`.`org_id` IN (6231, 6232, 6233, 6234)
AND (`details`.`end_at` BETWEEN '2017-05-31 16:00:00' AND '2017-06-13 16:00:00')
ORDER BY end_at desc
) as b
on `files`.record_id = b.record_id
WHERE (file_name IS NOT NULL )
LIMIT 30
输出如下
+----+-------------+--------------+-------+--------------------+--------------------+---------+------------------+---------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+--------------+-------+--------------------+--------------------+---------+------------------+---------+--------------------------+
| 1 | PRIMARY | <derived2> | ALL | NULL | NULL | NULL | NULL | 3844632 | Using where |
| 1 | PRIMARY | files | ref | idx_record | idx_record | 5 | b.record_id | 1 | Using where |
| 2 | DERIVED | details | range | idx_end_org_record | idx_end_org_record | 11 | NULL | 3844632 | Using where; Using index |
+----+-------------+--------------+-------+--------------------+--------------------+---------+------------------+---------+--------------------------+
如您所见,<derived2>
table 没有使用任何索引,这使得该查询几乎需要 1 秒才能完成。
感谢任何帮助!
此外,在查询中删除 WHERE (file_name IS NOT NULL )
没有任何区别。
而在 mysql 5.7 中,这个问题甚至不存在,但目前我正在尝试在 5.6 中解决这个问题。
我不明白子查询的意义所在。特别是,子查询中的 ORDER BY
是没有意义的。如果您将查询编写为两个 table 之间的直接连接,那么优化器应该能够利用连接列上的索引:
SELECT
id as file_id,
record_id,
recording_path
FROM files f
INNER JOIN details d
ON f.record_id = d.record_id AND
d.org_id IN (6231, 6232, 6233, 6234) AND
d.end_at BETWEEN '2017-05-31 16:00:00' AND '2017-06-13 16:00:00'
WHERE f.file_name IS NOT NULL
ORDER BY <some column> -- it doesn't make sense most of the time to use LIMIT
LIMIT 30 -- without ORDER BY
在 details
table 中的 record_id
、org_id
和 end_at
以及 file_name
中添加索引=17=] table,应该会给你一些性能改进。