我有这些 table 。
CREATE TABLE `movements` (
`movementId` mediumint(8) UNSIGNED NOT NULL,
`movementType` tinyint(3) UNSIGNED NOT NULL,
`deleted` tinyint(1) UNSIGNED NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
ALTER TABLE `movements`
ADD PRIMARY KEY (`movementId`),
ADD KEY `movementType` (`movementType`) USING BTREE,
ADD KEY `deleted` (`deleted`),
ADD KEY `movementId` (`movementId`,`deleted`);
CREATE TABLE `movements_items` (
`movementId` mediumint(8) UNSIGNED NOT NULL,
`itemId` mediumint(8) UNSIGNED NOT NULL,
`qty` decimal(10,3) UNSIGNED NOT NULL,
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
ALTER TABLE `movements_items`
ADD KEY `movementId` (`movementId`),
ADD KEY `itemId` (`itemId`),
ADD KEY `movementId_2` (`movementId`,`itemId`);
这个 View 称为“movements_items_view”。
SELECT
movements_items.itemId, movements_items.qty,
movements.movementId, movements.movementType
FROM movements_items
JOIN movements ON (movements.movementId=movements_items.movementId
AND movements.deleted=0)
第一个表有 5913 行,第二个表有 144992 行。
该 View 非常快,它在 0.0011s 内加载了 PhpMyAdmin 中的 20 个结果,但是当我要求对其进行 GROUP BY 时(我需要它使用 SUM() 进行统计)es:
SELECT * FROM movements_items_view GROUP BY itemId LIMIT 0,20
时间跳到 0.2 秒或更长,并导致移动连接时出现“Using where;Using tempor;Using filesort”。 感谢任何帮助,谢谢。
编辑:
我还通过 phpMyAdmin 运行此查询以尝试不使用该 View :
SELECT movements.movementId, movements.movementType, movements_items.qty
FROM movements_items
JOIN movements ON movements.movementId=movements_items.movementId
GROUP BY itemId LIMIT 0,20
而且性能是一样的。
编辑。这是解释
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE movements index PRIMARY,movementid movement_type 1 NULL 5913 Using index; Using temporary; Using filesort
1 SIMPLE movements_items ref movementId,itemId,movementId_2 movementId_2 3 movements.movementId 12 Using index
最佳答案
把它翻过来。看看这是否有效:
SELECT movementId, m.movementType, mi.qty
FROM
( SELECT movementId, qty
FROM movements_items
GROUP BY itemId
ORDER BY itemId
LIMIT 20
) AS mi
JOIN movements AS m USING(movementId)
诀窍是尽快达到LIMIT
。最初的方式是传输所有数据,而不仅仅是 20 行。
在movements_items
中,没有列或列组合是“唯一的”吗?如果是这样,请将其设为主键
。
在movement
中,KEY movingId (movementId,deleted)
是多余的,应该删除。
在movement_items
中,KEY movingId (movementId)
是多余的,应该被删除。
关于mysql GROUP BY 就一个 View 确实很慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59340374/