【发布时间】:2018-05-17 21:11:54
【问题描述】:
我有 2 个包含数百万行的 MySQL 表,我正在尝试执行查询选择以从两个表中获取特定数据列。尽管我的第一个良好期望是查询选择的执行需要几秒钟(大约 5 秒),并且索引应用于 WHERE 条件。
为 2 个 MySQL 表创建语句:
CREATE TABLE `T1` (
`T1_id` int(15) NOT NULL AUTO_INCREMENT,
`T1_val1` varchar(45) NOT NULL,
`T1_val2` varchar(45) NOT NULL,
`T1_val3` bigint(11) NOT NULL,
`T1_val4` datetime NOT NULL,
`T1_val5` varchar(100) NOT NULL,
`T1_val6` float NOT NULL,
`T1_val7` datetime NOT NULL,
`T1_val8` varchar(100) NOT NULL,
`T1_val9` varchar(100) NOT NULL,
`T1_val10` varchar(100) NOT NULL,
PRIMARY KEY (`T1_id`),
KEY `T1_val4` (`T1_val4`)
) ENGINE=InnoDB AUTO_INCREMENT=53885653 DEFAULT CHARSET=latin1;
CREATE TABLE `T2` (
`T2_id` int(11) NOT NULL,
`T2_val1` float NOT NULL,
`T2_val2` float NOT NULL,
`T2_val3` varchar(45) NOT NULL,
PRIMARY KEY (`T2_id`),
KEY `T2_val3` (`T2_val3`),
KEY `T2_val1_2` (`T2_val1`,`T2_val2`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
如您所见,两个表都有一个 AI 主键 和 外键,它们之间匹配为 one-to-one relationship(T1_id 和 T2_id)。我们在T1 上为T1_val4 应用了索引,它采用日期时间格式。
选择查询
SELECT
T1_val5,
T2_val1,
T2_val2,
T2_val3,
T1_val9,
count(T2_val1) as cnt,
T1_val4
FROM
T1 USE INDEX (T1_val4)
INNER JOIN T2
ON T1.T1_id = T2.T2_id
WHERE
T1_val4 BETWEEN '2016-02-18 15:00:00'
AND '2016-02-18 16:59:59'
GROUP BY
T2_val1,
T2_val2,
T2_val3,
T1_val9,
T1_val5
order by
T1_val4 ASC;
如您所见,我为索引指定了一个提示,以便告诉 MySQL 将该特定索引用于日期时间列。实际上,如果我将 WHERE 条件中的日期时间范围扩展到几个小时。例如BETWEEN '2016-02-18 15:00:00' AND '2016-02-18 23:59:59',执行时间会增长到 50/100 秒。可能我在逻辑上遗漏了一些东西。
EXPLAIN 输出
+-------+---------------+-----------+-----------+-------------------+-----------+---------------+-----------+-----------+------------------------------------------------------------+
| ID | SELECT_TYPE | TABLE | TYPE | POSSIBLE_KEYS | KEY | KEY_LEN | REF | ROWS | EXTRA |
+-------+---------------+-----------+-----------+-------------------+-----------+---------------+-----------+-----------+------------------------------------------------------------+
| 1 | SIMPLE | T1 | range | T1_val4 | T1_val4 | 5 | NULL | 10670 | "Using index condition; Using temporary; Using filesort" |
+-------+---------------+-----------+-----------+-------------------+-----------+---------------+-----------+-----------+------------------------------------------------------------+
| 1 | SIMPLE | T2 | eq_ref | PRIMARY | PRIMARY | 4 | T1_id | 1 | NULL |
+-------+---------------+-----------+-----------+-------------------+-----------+---------------+-----------+-----------+------------------------------------------------------------+
使用复合索引更新的 EXPLAIN 输出
(根据@O. Jones 的建议)
+-------+---------------+-----------+-----------+------------------------------+-----------+---------------+-----------+-----------+---------------------------------------------------------------+
| ID | SELECT_TYPE | TABLE | TYPE | POSSIBLE_KEYS | KEY | KEY_LEN | REF | ROWS | EXTRA |
+-------+---------------+-----------+-----------+------------------------------+-----------+---------------+-----------+-----------+---------------------------------------------------------------+
| 1 | SIMPLE | T1 | range | "PRIMARY,ix_rlf" | ix_rlf | 5 | NULL | 10906 | "Using where; Using index; Using temporary; Using filesort" |
+-------+---------------+-----------+-----------+------------------------------+-----------+---------------+-----------+-----------+---------------------------------------------------------------+
| 1 | SIMPLE | T2 | eq_ref | "PRIMARY,ix_cc" | PRIMARY | 4 | T1_id | 1 | NULL |
+-------+---------------+-----------+-----------+------------------------------+-----------+---------------+-----------+-----------+---------------------------------------------------------------+
ix_rlf 是T1_val4、T1_val9、T1_val5 的复合索引,ix_cc 是@Tom Shir 为由@ 制成的T2 建议的复合索引987654338@, T2_val1, T2_val2, T2_val3.
查询执行计划可视架构
(将 2 HOURS 视为间隔,在本例中查询结果约为 6632 行,执行时间为 6/7 秒)
【问题讨论】:
-
请阅读此meta.stackoverflow.com/a/271056 请特别注意查询性能部分。请edit您的问题向我们展示
EXPLAIN输出和其他相关信息。顺便说一句,您的GROUP BY子句还需要提及T1_val4,即您的日期戳列。 -
你是对的!请给我几分钟,我会添加 EXPLAIN 输出。
-
innodb_buffer_pool_size的值是多少?你有多少内存? -
innodb_buffer_pool_size是 6123683840 -
请注意,
ix_cc未被选中。无论如何,PRIMARY几乎一样好。
标签: mysql database performance select query-performance