关于 mysql 加了 limit 反而变慢的问题?
Posted 甜菜波波
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于 mysql 加了 limit 反而变慢的问题?相关的知识,希望对你有一定的参考价值。
SELECT * FROM pre_forum_post WHERE tid=6584344 AND `inv`=\'0\' AND `uid`=\'6547981\' ORDER BY dateline DESC limit 4
;
上面一条正常执行需要 16-20 秒.
SELECT * FROM pre_forum_postWHERE tid=6584344 AND `inv`=\'0\' AND `uid`=\'6547981\' ORDER BY dateline DESC ;
下面的只需要 0.2 秒左右。请大神帮帮忙.
走的索引不一样, 第一个 key 是 dateline, 第二个是 authorid, 根据业务建议优化一下索引.
WHERE + ORDER BY的索引优化,形如:
SELECT [column1],[column2],…. FROM [TABLE] WHERE [columnX] = [value] ORDER BY [sort];
建立一个联合索引(columnX,sort)来实现order by 优化。
回复
@ffvsnn520 : Extra信息不完整, 看看有没有 filesort.
mysql对语句优化的时候, 选择了不同的索引, 因为你没有 联合索引,所以 当 where 后面走了索引的时候(比如你说的主键), order by 则不会走索引, 如果你的结果集很大, filesort 也会很漫长...
如果mysql走了 order by 索引,那么where就不会走索引,如果你的sql在查询上需要花大量时间,而结果集filesort排序很快的话,那么没走where索引的查询就会非常慢...
所以建议就是 尽量让 where 和 order by 都走索引...
MySQL关于View调用Function效率变慢的问题
【中文标题】MySQL关于View调用Function效率变慢的问题【英文标题】:MySQL on the problem of slowing down the efficiency of View calling Function 【发布时间】:2021-11-09 06:06:42 【问题描述】:我将问题解释如下:
(1) 数据库版本:MySQL 8.0.23
(2) 数据表名称:TB_202104 该数据表用于存储从 2021-04-01 00:00:00 到 2021-04-30 23:59:59 的数据。有99200872条数据 数据表结构如下:
创建表 TB_202104 ( OID INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, ChannelOID INT(10) 无符号非空, 时间戳 TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, 值双非空, LastUpdate TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, 使用 BTREE 的主键(OID,时间戳), INDEX IDX_ChaOID(ChannelOID) 使用 BTREE, INDEX IDX_ChaOID_Timsta(ChannelOID, Timestamp) 使用 BTREE, INDEX IDX_Timsta(时间戳)使用 BTREE ) COMMENT='保存 2021/04 传感器数据' 整理='utf8_unicode_ci' 按范围分区 (unix_timestamp(`Timestamp`)) (分区 p0 值小于(1617840000)引擎 = InnoDB, 分区 p1 值小于 (1618444800) 引擎 = InnoDB, 分区 p2 值小于 (1619049600) 引擎 = InnoDB, 分区 p3 值小于 (1619827200) 引擎 = InnoDB, 分区 pMax 值小于 MAXVALUE 引擎 = InnoDB );(3) 函数名:GetMyStartDateTime 函数结构如下:
创建函数 GetMyStartDateTime() 返回时间戳 语言 SQL 不确定的 没有 SQL SQL 安全定义器 COMMENT '获取自定义开始日期和时间' 开始 返回'2021-05-01 00:00:00'; 结尾这个View表的目的是调用GetMyStartDateTime()来过滤Timestamp字段中的日期和时间数据 View表结构如下:
(4)查看表名:DynamicTB
ALTER ALGORITHM = 未定义的 SQL 安全定义器视图`DynamicTB` 作为 选择 ChannelOID 作为 ChannelOID, 时间戳作为时间戳, 价值作为价值 来自 TB_202104 其中(时间戳> = GetMyStartDateTime()) 限制 1 ;(5)当我执行以下指令时,执行时间异常长,执行未完成
选择 * 从 DynamicTB问题是在DynamicTB的View表中搜索到的TB_202104数据表在2021-05-01 00:00:00根本没有数据。
(6) 但是如果我先把DynamicTB如下:
ALTER ALGORITHM = 未定义的 SQL 安全定义器视图`DynamicTB` 作为 选择 ChannelOID 作为 ChannelOID, 时间戳作为时间戳, 价值作为价值 来自 TB_202104,其中(时间戳 >= '2021-05-01 00:00:00') 限制 1 ;然后执行:
选择 * 从 DynamicTB执行不到一秒就完成了,因为 TB_202104 在 2021-05-01 00:00:00 之后没有时间数据。
(7)目前的问题是在DynamicTB的View表中,只要调用GetMyStartDateTime()这个函数, 它会变得异常缓慢,甚至根本无法完成。
GetMyStartDateTime() 只是返回 2021-05-01 00:00:00 的值,为什么在 DynamicTB 的 View 表中调用 GetMyStartDateTime() 得到相同的值 执行异常有问题吗?
感谢您的回复。
【问题讨论】:
每秒大约 40 次插入。同一 OID 的两个条目是否有可能在同一秒内出现? 【参考方案1】:没有ORDER BY
的LIMIT
是在自找麻烦。引擎可以免费为您提供它喜欢的任何行。在LIMIT 1
之前添加ORDER BY Timestamp
。
将函数改为DETERMINISTIC
;这可能会阻止查询进行表扫描。
【讨论】:
以上是关于关于 mysql 加了 limit 反而变慢的问题?的主要内容,如果未能解决你的问题,请参考以下文章
为啥 MySQL 查询在使用 LIMIT 和 Order BY 时会变慢?