【问题标题】: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...的输出

  • id = 1
  • select_type = '简单'
  • "table" = 'Twit'
  • 分区 = null
  • type = 'ref'
  • possible_keys = 'User_ID,User_ID_2'
  • "key" = 'User_ID'
  • key_len = '8'
  • ref = 'const'
  • “行”= 298
  • 过滤 = 100
  • Extra = '使用索引条件';

变量:

  • 'innodb_buffer_pool_size', Value = '4294967296';

为了更清楚,我在 python 循环中调用 SELECT 请求。如果我已经为该用户运行了 SELECT 请求,则每次迭代都非常快,否则非常慢。是否擦除 RAM(服务器重启)都没有关系。

谢谢。

【问题讨论】:

  • 该死,这就是我不想听到的!!!意味着没有优化可能吗?不过谢谢
  • 其实这个看起来像一个内置的优化功能。大声笑。
  • 查询并未准确存储,但数据库的执行计划已存储,第一次执行期间获取的部分(或全部)数据也已存储。这是设计使然 - 缓冲区缓存(在 RAM 中,由 db 进程使用)是用于提高大多数现代数据库整体性能的最重要元素之一。
  • 缓存是原因

标签: mysql database database-design


【解决方案1】:

有两个“缓存”可以解释时序“加速”。

  • InnoDB 使用其“缓冲池”来避免从磁盘重新加载内容。
  • 如果“查询缓存”已打开,则第二次运行可能会“立即”返回,因为 QC 缓存了结果集。

“然后减速到 10 用户/秒的速度”——闻起来像数据尚未缓存。

不要在没有ORDER BY 的情况下使用LIMIT,除非您不在乎返回哪些行。

cursorSQL 是什么?不同的客户做事不同;了解您使用的语言可能很重要。

请提供SHOW CREATE TABLE TwitEXPLAIN SELECT ...,以便我们了解更多详情。

请解释“为第 1000 个用户运行它”是什么意思。那是1000个选择吗?一个选择 LIMIT 1000?还有什么?

你有多少内存? innodb_buffer_pool_size的值是多少?

【讨论】:

  • 感谢您的回答。 - 我不清楚“缓存”是什么意思。它是仅缓存 RAM,还是也可以“硬缓存”。因为之前的观察结果适用于我之前是否运行过查询,或者如果我刚刚重新启动服务器(并清除了 RAM ......)。 - cursorSQL 来自我正在使用的 python-mysqlconnector。在 python 中调用 SQL 查询我更新了我的帖子以提供您问题的答案。再次感谢!
  • 为了清楚起见,我在 python 循环中调用 SELECT 请求。如果我已经为该用户运行了 SELECT 请求,则每次迭代都非常快,否则非常慢。是否擦除了 RAM(服务器重新启动)并不重要。我也知道这不是最优的,它可以在单个查询而不是循环中调用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-01-02
  • 1970-01-01
  • 2012-01-17
  • 2014-10-09
  • 2011-09-30
  • 2017-04-10
  • 2021-06-13
相关资源
最近更新 更多