我正在寻找一种方法来优化以下 MySQL 存储过程:
DECLARE total BIGINT UNSIGNED;
DROP TEMPORARY TABLE IF EXISTS tempTable;
CREATE TEMPORARY TABLE tempTable(identityValue BIGINT(20) UNSIGNED );
INSERT INTO tempTable
SELECT
`getIdentity`(samples.`originalId`)
FROM
`rawData`
WHERE
`samples`.`groupId` = _group;
SET total = (
SELECT
IFNULL( SUM(getTotal(rawData.id, NULL, NULL)), 0)
FROM
rawData
WHERE
rawData.user= _user AND
getIdentity(rawData.id) IN (SELECT * FROM tempTable)
);
DROP TEMPORARY TABLE IF EXISTS tempTable;
RETURN total;
getIdentity 函数如下所示:
RETURN (SELECT IFNULL(MIN(id1), _id)
FROM `equivalences` WHERE
id1 = _id OR id2 = _id);
getTotal 函数如下所示:
BEGIN
DECLARE total INT;
IF (_startDate IS NULL OR _endDate IS NULL) THEN
SET total = (SELECT IFNULL(SUM(ops.downloads),0)
FROM objects, ops
WHERE objects.id = _objectId AND ops.objectId = _objectId);
ELSE
SET total = (SELECT IFNULL(SUM(ops.downloads),0)
FROM objects, ops
WHERE objects.id = _objectId AND ops.objectId = _objectId AND
ops.`date` BETWEEN _startDate AND _endDate);
END IF;
RETURN total;
END
现在运行大约需要 350 毫秒。大多数时间似乎与我正在创建的临时表有关。使用 EXPLAIN 后,这些表已经有了我认为必要的索引。
最佳答案
我猜你没有将内存用于临时表。尝试一下
CREATE TEMPORARY TABLE tempTable(identityValue BIGINT(20) UNSIGNED ) engine=memory;
对于 mysql >= 5.6,您可以在配置中设置 default_tmp_storage_engine=MEMORY
使其成为永久选项。
由于您已经拥有良好的索引,因此分析查询其余部分的优化是否有意义,取决于临时表中的数据量。
关于mysql - 是否可以优化这个MySql查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37648132/