【发布时间】:2019-07-18 08:43:02
【问题描述】:
我有一个关于 mysql 的表和两个性能完全不同的查询。我已经提取了查询计划,但我无法完全理解性能差异背后的原因。
桌子:
+-------------+----------------------------------------------+------------------------------------+
| TableA | | |
+-------------+----------------------------------------------+------------------------------------+
| id | int(10) unsigned NOT NULL AUTO_INCREMENT | |
| userId | int(10) | unsigned DEFAULT NULL |
| created | timestamp | NOT NULL DEFAULT CURRENT_TIMESTAMP |
| PRIMARY KEY | id | |
| KEY userId | userId | |
| KEY created | created | |
+-------------+----------------------------------------------+------------------------------------+
键/索引:id 字段上的主键,userId 字段 ASC 上的键
,created 字段 ASC 上的另一个键。
tableA 是一个很大的表,它包含数百万行。
我在这张表上运行的查询是:
id为1234的用户在这个表中有150万条记录。我想获取其最新的 100 行。为了实现这一点,我有 2 个不同的查询:
查询 1:
SELECT * FROM tableA USE INDEX (userId)
WHERE userId=1234 ORDER BY created DESC LIMIT 100;
查询 2:
SELECT * FROM tableA
WHERE userId=1234 ORDER BY id DESC LIMIT 100;
由于tableA 的id 字段是自动递增的,所以保持最新的条件。这 2 个查询返回相同的结果。但是,存在巨大的性能差异。
查询计划是:
+----------+-----------------------------------------------+-------------------------------+------+---------------------------------------+
| Query No | Operation | Params | Raws | Raw desc |
+----------+-----------------------------------------------+-------------------------------+------+---------------------------------------+
| Query 1 | Sort(using file sort) Unique index scan (ref) | table: tableA; index: userId; | 2.5M | Using index condition; Using filesort |
| Query 2 | Unique index scan (ref) | table: tableA; index: userId; | 2.5M | Using where |
+----------+-----------------------------------------------+-------------------------------+------+---------------------------------------+
+--------+-------------+
| | Performance |
+--------+-------------+
| Query1 | 7,5 s |
+--------+-------------+
| Query2 | 741 ms |
+--------+-------------+
我了解到Query 1 有一个排序操作。在每个查询中,使用的索引是userId。但是为什么查询 2 中没有使用排序呢?主索引如何影响?
Mysql 5.7
编辑:表格上有更多列,我从上面的表格定义中提取出来。
【问题讨论】:
-
您忘记告诉我们您已经在此表上创建了哪些索引。
-
这两个查询的相对性能如何?
-
@TimBiegeleisen 我已经在表格中添加了性能数据和索引。
-
性能一点也不意外。 MySQL 不想使用索引
userId,所以当你强制它时,性能会下降。请参阅我的答案以获取应该可以正常工作的索引。 -
@TimBiegeleisen 我支持你的警告。但我不确定您是否已阅读我在答案下的评论。如果我没有明确说索引,那么查询就会超时,它永远不会返回。它的性能更差。因此,您可以在没有“使用索引”字段的情况下考虑我的问题。主要问题仍然有效。
标签: mysql performance innodb