为啥 MySQL 查询在我第二次运行时更快?
Posted
技术标签:
【中文标题】为啥 MySQL 查询在我第二次运行时更快?【英文标题】:Why MySQL query is faster the second time I run it?为什么 MySQL 查询在我第二次运行时更快? 【发布时间】:2017-04-06 07:51:06 【问题描述】:我刚刚观察到一个非常奇怪的问题,这实际上可能有助于我更好地理解我的数据库行为并更好地设计它。
首先,这是我们所说的 mysql 数据库。 User_ID 字段有索引。
这是我运行的代码:
query3 =("SELECT Content FROM Twit "
"WHERE User_ID = %s "
"limit 25 ")
for userid, c_word in user22_list:
cursorSQL.execute(query3, (userid,))
由于某种原因,我不明白什么时候我为 200 个第一个用户运行它,然后停止它,每 10 个用户大约需要 1 秒,非常慢。
但是如果几分钟后我为第一个 1000 个用户运行它,它将在不到一秒的时间内达到 200 个,然后减速到 10 个用户/秒的速度,依此类推如果我在那之后运行它 5000(非常快到 1000,之后慢)。
问题:
能否将查询临时存储在某处(在我服务器的 RAM 中?)以解释其速度? 您有什么方法可以加快这个过程吗?***** 编辑1: 根据要求:
SHOW CREATE TABLE Twit
的输出
Table Create Table Twit CREATE TABLE `Twit` ( `ID_num` bigint(45) NOT NULL, `Content` varchar(250) COLLATE utf8mb4_unicode_ci DEFAULT NULL, `User_ID` bigint(24) NOT NULL, `Location` varchar(70) COLLATE utf8mb4_unicode_ci DEFAULT NULL, `Date_create` datetime NOT NULL, `Retweet_count` int(7) NOT NULL, `isRetweet` tinyint(1) NOT NULL, `hasReetweet` tinyint(1) NOT NULL, `Original` bigint(45) DEFAULT NULL, `Url` varchar(150) COLLATE utf8mb4_unicode_ci DEFAULT NULL, `Favorite_count` int(7) NOT NULL, PRIMARY KEY (`ID_num`), KEY `User_ID` (`User_ID`), KEY `Date_create` (`Date_create`), KEY `User_ID_2` (`User_ID`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
EXPLAIN SELECT Content From...
的输出
变量:
'innodb_buffer_pool_size', Value = '4294967296';
为了更清楚,我在 python 循环中调用 SELECT 请求。如果我已经为该用户运行了 SELECT 请求,则每次迭代都非常快,否则非常慢。是否擦除 RAM(服务器重启)都没有关系。
谢谢。
【问题讨论】:
Should I blame caching, yes!:)
该死,这就是我不想听到的!!!意味着没有优化可能吗?不过谢谢
其实这个看起来像一个内置的优化功能。大声笑。
查询并未准确存储,但数据库的执行计划已存储,第一次执行期间获取的部分(或全部)数据也已存储。这是设计使然 - 缓冲区缓存(在 RAM 中,由 db 进程使用)是用于提高大多数现代数据库整体性能的最重要元素之一。
缓存是原因
【参考方案1】:
有两个“缓存”可以解释时序“加速”。
InnoDB 使用其“缓冲池”来避免从磁盘重新加载内容。 如果“查询缓存”已打开,则第二次运行可能会“立即”返回,因为 QC 缓存了结果集。“然后减速到 10 用户/秒的速度”——闻起来像数据尚未缓存。
不要在没有ORDER BY
的情况下使用LIMIT
,除非您不在乎返回哪些行。
cursorSQL
是什么?不同的客户做事不同;了解您使用的语言可能很重要。
请提供SHOW CREATE TABLE Twit
和EXPLAIN SELECT ...
,以便我们了解更多详情。
请解释“为第 1000 个用户运行它”是什么意思。那是1000个选择吗?一个选择 LIMIT 1000?还有什么?
你有多少内存? innodb_buffer_pool_size
的值是多少?
【讨论】:
感谢您的回答。 - 我不清楚“缓存”是什么意思。它是仅缓存 RAM,还是也可以“硬缓存”。因为之前的观察结果适用于我之前是否运行过查询,或者如果我刚刚重新启动服务器(并清除了 RAM ......)。 - cursorSQL 来自我正在使用的 python-mysqlconnector。在 python 中调用 SQL 查询我更新了我的帖子以提供您问题的答案。再次感谢! 为了清楚起见,我在 python 循环中调用 SELECT 请求。如果我已经为该用户运行了 SELECT 请求,则每次迭代都非常快,否则非常慢。是否擦除了 RAM(服务器重新启动)并不重要。我也知道这不是最优的,它可以在单个查询而不是循环中调用。以上是关于为啥 MySQL 查询在我第二次运行时更快?的主要内容,如果未能解决你的问题,请参考以下文章
当我第二次设置它的 ItemsSource 时,为啥这个选择器会崩溃?
为啥当我第二次使用完全相同的参数调用 IMMUTABLE 函数时,计划时间会加倍?