Mysql GROUP BY在视图上真的很慢

问题描述 投票:0回答:1

我有这些表。

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.0011s内将20个结果加载到PhpMyAdmin中,但是一旦我要求对它进行GROUP BY(我需要它使用SUM()进行统计):

SELECT * FROM movements_items_view GROUP BY itemId LIMIT 0,20

时间跳到0.2s或更长时间,它会导致运动中出现“在何处使用;使用临时文件;使用文件排序”。任何帮助表示感谢,谢谢。

编辑:

我也通过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
mysql optimization indexing view
1个回答
0
投票
将其内翻。看看是否可行:

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)是多余的,应该删除。

© www.soinside.com 2019 - 2024. All rights reserved.