MySQL性能 - 从大表中选择和删除

时间:2017-12-03 18:24:17

标签: mysql performance query-performance

我有一个名为" queue"的大表。它现在有1200万条记录。

CREATE TABLE `queue` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `userid` varchar(64) DEFAULT NULL,
  `action` varchar(32) DEFAULT NULL,
  `target` varchar(64) DEFAULT NULL,
  `name` varchar(64) DEFAULT NULL,
  `state` int(11) DEFAULT '0',
  `timestamp` int(11) DEFAULT '0',
  `errors` int(11) DEFAULT '0',
  PRIMARY KEY (`id`),
  UNIQUE KEY `idx_unique` (`userid`,`action`,`target`),
  KEY `idx_userid` (`userid`),
  KEY `idx_state` (`state`)
) ENGINE=InnoDB;

多个PHP工作人员(150)同时使用此表。

他们选择一条记录,使用所选数据执行网络请求,然后删除记录。

我从select和delete查询中获得混合执行时间。 delete命令是否锁定表?

这种情况的最佳方法是什么?

  1. SELECT记录+ NETWORK请求+删除记录

  2. SELECT记录+ NETWORK请求+ MARK记录已完成+ DELETE使用cron不时完成记录(我不想要更大的表格)。

  3. 注意:队列每分钟都会获得新记录,但INSERT查询不是问题所在。

    感谢任何帮助。

1 个答案:

答案 0 :(得分:1)

"不要排队,只是这样做"。也就是说,如果任务相当快,最好简单地执行操作而不排队。数据库不能建立良好的排队机制。

DELETE不会锁定InnoDB表。但是,你可以写一个看起来很顽皮的DELETE。让我们看看您的实际SQL,以便我们可以改进它。

12M记录?这是一个巨大的积压;什么了?

缩小数据类型,使表格不是千兆字节:

  • action只是一小部分可能的值?将其标准化为1字节ENUMTINYINT UNSIGNED
  • 同意state - 当然它不需要4字节代码?
  • 不需要INDEX(userid),因为已经有一个以UNIQUE开头的索引(userid)。
  • 如果state只有几个值,则不会使用该索引。让我们看看你的入队和出队查询,这样我们就可以讨论如何去掉那个索引或者让它“复合”。 (并且很有用)。
  • MAX(id)的当前值是什么?是否有可能超过INT UNSIGNED的约40亿的当前限额?
  • PHP如何使用队列?它是否通过InnoDB交易挂在项目上?这击败了任何并行性!或者它会改变state。告诉我们代码;也许锁和&解锁可以减少侵入性。应该可以运行单个自动提交的UPDATE来获取一行及其id。然后,稍后,自动提交DELETE,影响很小。
  • 我没有看到抓取待处理项目的好索引。再次,让我们看看代码。
  • 150似乎很多 - 您是否尝试过更少的?他们可能彼此磕磕绊绊。
  • 是否启用了Slowlog(long_query_time的值较低)?如果是这样的话,我想知道什么是最差的'查询。在这种情况下,答案可能会令人惊讶。
相关问题