mysql GROUP BY 真的慢上一个视图
Posted
技术标签:
【中文标题】mysql GROUP BY 真的慢上一个视图【英文标题】:Mysql GROUP BY really slow on a view 【发布时间】:2019-12-15 00:47:29 【问题描述】:我有这些表。
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`);
这个视图称为“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 行。
视图非常快,它会在 0.0011 秒内在 phpMyAdmin 中加载 20 个结果,但只要我在其上请求 GROUP BY(我需要它使用 SUM() 进行统计)es:
SELECT * FROM movements_items_view GROUP BY itemId LIMIT 0,20
时间跳到 0.2 秒或更多,它会导致“使用 where;使用临时;使用文件排序”在移动连接上。 任何帮助表示赞赏,谢谢。
编辑:
我还通过 phpMyAdmin 运行此查询以尝试不使用视图:
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 语句是否与添加的 group by 一起运行? 您从带有 group by 的视图中选择确实会读取所有记录;这似乎无法与您在 phpmyadmin 中返回 20 个结果的操作相提并论。 @ysth GROUP BY 查询也在 phpMyAdmin 中运行,因此需要 0.2 秒或更长时间才能获得 20 个结果。我正在编辑问题,我的错误。谢谢。 mysql 中的视图访问其底层索引的能力极为有限。因此,在我看来,它们毫无意义 @Strawberry 我理解,但它们让我节省了大量的 PHP 编码。我还尝试在不通过视图的情况下运行“本机”查询,并且性能是相同的。我可以做些什么来使用更好的索引或避免使用 GROUP BY? 【参考方案1】:把它翻过来。看看这是否有效:
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
中,是否没有“唯一”列或列组合?如果是这样,请将其设为PRIMARY KEY
。
在movement
中,KEY movementId (movementId,deleted)
是多余的,应该删除。
在movement_items
中,KEY movementId (movementId)
是多余的,应该删除。
【讨论】:
以上是关于mysql GROUP BY 真的慢上一个视图的主要内容,如果未能解决你的问题,请参考以下文章
带有 GROUP BY 的这个 MySQL 视图的 MS 版本?
使用 LEFT JOIN 的 MySQL 视图中的问题... GROUP BY