加速MySQL FUNCTION调用的方法是什么?

时间:2017-05-18 15:16:36

标签: mysql

似乎在MySQL查询中调用FUNCTION的速度非常慢,那么我们有什么办法来解决这个问题呢?

是否存在像C / C ++这样的“内联”函数(= MERGE算法不适用于VIEW而是适用于FUNCTION)?

还有其他方法可以加快FUNCTION 调用本身(例如:在展示中,很难固定函数本身,而缓慢来自其调用,而不是其内容) ?

示例

我创建一个整数表(~500k),并使用SELECT子句对其进行WHERE。这运行大约1秒钟。然后,我执行相同的SELECT,但将WHERE微积分放在FUNCTION中,执行时间超过10倍(约30秒)。

有没有办法继续使用FUNCTION(因为在实践中,我在WHERE但是在不同的列上执行相同的微积分,所以就像拥有WHERE x blabla AND y blabla AND z blabla...所以我想要将所有blabla合并到一个函数中而不会耗尽执行时间?

CREATE TABLE IF NOT EXISTS `integers` (
    `n` INT(10) UNSIGNED NOT NULL,
    PRIMARY KEY (`n`)
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB
;
TRUNCATE TABLE integers;
INSERT INTO integers (n) VALUES (0),(1),(2),(3),(5);
INSERT IGNORE INTO integers (n) (
    SELECT x.n+5*(y.n+5*(z.n))
    FROM integers AS x
    INNER JOIN integers as y
    INNER JOIN integers as z
);
INSERT IGNORE INTO integers (n) (
    SELECT x.n+95*(y.n+95*(z.n))
    FROM integers AS x
    INNER JOIN integers as y
    INNER JOIN integers as z
    WHERE y.n > 0 OR z.n > 0
);
SELECT COUNT(*) FROM integers;
-- Shows it has about 568k rows

DROP FUNCTION IF EXISTS `test_speed`;

DELIMITER $$

CREATE FUNCTION `test_speed`(
    `n` INT UNSIGNED
)
RETURNS BOOLEAN
LANGUAGE SQL
DETERMINISTIC
NO SQL
SQL SECURITY DEFINER
COMMENT ''
BEGIN

    RETURN (n % 128 = 0);

END$$

DELIMITER ;

SET @timer := UNIX_TIMESTAMP();

SELECT *, (i.n+1e6*j.n)
FROM integers AS i
INNER JOIN integers AS j ON j.n < 32
WHERE (i.n+1e6*j.n) % 128 = 0
;
-- Takes like 1 second

SET @d1 := UNIX_TIMESTAMP() - @timer;

SET @timer := UNIX_TIMESTAMP();

SELECT *, (i.n+1e6*j.n)
FROM integers AS i
INNER JOIN integers AS j ON j.n < 32
WHERE test_speed(i.n+1e6*j.n)
;
-- Takes like 30 seconds

SET @d2 := UNIX_TIMESTAMP() - @timer;

SELECT @d1, @d2;
-- Shows the durations

请注意,两个查询都具有完全相同的EXPLAIN

id  select_type table   partitions  type    possible_keys   key key_len ref rows    filtered    Extra
1   SIMPLE      j       \N          range   PRIMARY         PRIMARY 4   \N  23      100.00      Using where; Using index
1   SIMPLE      i       \N          index   \N              PRIMARY 4   \N  568625  100.00      Using where; Using index; Using join buffer (Block Nested Loop)

FUNCTION来电的第二次调用非常慢......

0 个答案:

没有答案