Arthur1977 2021-09-14 11:17 采纳率: 0%
浏览 12

MySQL 关于 View 呼叫 Function 效率变慢的问题

您好,我将问题说明如下:
(1) 资料库版本 : MySQL 8.0.23
(2) 资料表 名称 : TB_202104
这个资料表用来储存 2021-04-01 00:00:00 到 2021-04-30 23:59:59 这一段期间的资料,有 99200872 笔资料
资料表结构如下 :

CREATE TABLE TB_202104 (
    OID INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
    ChannelOID INT(10) UNSIGNED NOT NULL,
    Timestamp TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    Value DOUBLE NOT NULL,
    LastUpdate TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    PRIMARY KEY (OID,Timestamp) USING BTREE,
    INDEX IDX_ChaOID(ChannelOID) USING BTREE,
    INDEX IDX_ChaOID_Timsta(ChannelOID, Timestamp) USING BTREE,
    INDEX IDX_Timsta (Timestamp) USING BTREE
    )
    COMMENT='储存 2021/04 感测器资料'
    COLLATE='utf8_unicode_ci'
    PARTITION BY RANGE (unix_timestamp(`Timestamp`))
    (PARTITION p0 VALUES LESS THAN (1617840000) ENGINE = InnoDB,
     PARTITION p1 VALUES LESS THAN (1618444800) ENGINE = InnoDB,
     PARTITION p2 VALUES LESS THAN (1619049600) ENGINE = InnoDB,
     PARTITION p3 VALUES LESS THAN (1619827200) ENGINE = InnoDB,
     PARTITION pMax VALUES LESS THAN MAXVALUE ENGINE = InnoDB
    );

(3) Function 名称 : GetMyStartDateTime
Function 结构如下:

CREATE FUNCTION GetMyStartDateTime()
    RETURNS timestamp
    LANGUAGE SQL
    NOT DETERMINISTIC
    NO SQL
    SQL SECURITY DEFINER
    COMMENT '取得 自订 开始日期时间'
    BEGIN 

    RETURN '2021-05-01 00:00:00';

    END

(4) View 表名称 : DynamicTB
这个 View 表的用途是,呼叫 GetMyStartDateTime() , 过滤 Timestamp 栏位 的日期时间资料
View 表结构如下 :

ALTER ALGORITHM = UNDEFINED SQL SECURITY DEFINER VIEW DynamicTB
    AS 
    select ChannelOID AS ChannelOID,
           Timestamp AS Timestamp,
           Value AS VALUE 
    from TB_202104 
    where (Timestamp >= GetMyStartDateTime()) 
    limit 1 ;

(5) 当我执行以下指令,执行的时间变得异常的漫长,也没有执行完成

SELECT * FROM DynamicTB

问题是 DynamicTB 这个View 表 里搜寻的 TB_202104 资料表根本没有 在 2021-05-01 00:00:00 的资料。

(6) 但是如果我先把 DynamicTB 如下 :

ALTER ALGORITHM = UNDEFINED SQL SECURITY DEFINER VIEW DynamicTB
    AS 
    select ChannelOID AS ChannelOID,
           Timestamp AS Timestamp,
           Value AS VALUE 
         
    from TB_202104 where (Timestamp >= '2021-05-01 00:00:00') 
    limit 1 ;

然后执行 :

SELECT * FROM DynamicTB

执行不到 一秒就完成了,因为 TB_202104 根本就没有 2021-05-01 00:00:00 开始及之后的时间资料。
(7) 目前感觉问题在于 在 DynamicTB 这个 View 表中,只要是呼叫 GetMyStartDateTime() 这个 Function 就会变成异常的慢,甚至根本无法执行完成。
GetMyStartDateTime() 也只是回传 '2021-05-01 00:00:00' 这个值而已,为何 在 DynamicTB 这个 View 表中呼叫 GetMyStartDateTime() 取得相同的值
就有执行异常的问题?

感谢您的回覆及协助。

  • 写回答

1条回答 默认 最新

  • CSDN专家-Time 2021-09-14 11:19
    关注

    因为时间戳转字符串的计算很复杂。

    img


    而且这是全表扫描。

    评论

报告相同问题?

问题事件

  • 创建了问题 9月14日

悬赏问题

  • ¥15 素材场景中光线烘焙后灯光失效
  • ¥15 请教一下各位,为什么我这个没有实现模拟点击
  • ¥15 执行 virtuoso 命令后,界面没有,cadence 启动不起来
  • ¥50 comfyui下连接animatediff节点生成视频质量非常差的原因
  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 保护模式-系统加载-段寄存器