尽管有索引,mysql select查询仍很慢

发布于 2024-11-01 19:28:53 字数 1911 浏览 0 评论 0原文

好吧,事情是这样的:

我有一个名为 Mails 的漂亮的小 4Gb 表,我在其中执行以下两个查询:

SELECT * FROM Mails WHERE sent = 1 ORDER BY date ASC LIMIT 600;  // 200ms
SELECT * FROM Mails WHERE sent = 0 ORDER BY date ASC LIMIT 600;  // >9000ms

发送类型之间的关系如下:

0    192070
1   1112341
2   11992
3   5369

创建语句是这样的:

CREATE TABLE `Mails` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `idMail` varchar(100) COLLATE utf8_bin NOT NULL,
  `type` varchar(100) COLLATE utf8_bin DEFAULT NULL,
  `idSender` varchar(100) COLLATE utf8_bin DEFAULT NULL,
  `senderfName` varchar(100) COLLATE utf8_bin DEFAULT NULL,
  `senderlName` varchar(100) COLLATE utf8_bin DEFAULT NULL,
  `senderMail` varchar(100) COLLATE utf8_bin DEFAULT NULL,
  `receiverMail` varchar(100) COLLATE utf8_bin DEFAULT NULL,
  `reference` varchar(100) COLLATE utf8_bin DEFAULT NULL,
  `mailContent` text COLLATE utf8_bin,
  `mailSubject` varchar(100) COLLATE utf8_bin DEFAULT NULL,
  `sent` int(1) unsigned DEFAULT '0',
  `opened` int(1) unsigned DEFAULT '0',
  `clicked` int(1) unsigned DEFAULT '0',
  `completed` int(1) unsigned DEFAULT '0',
  `abstract` varchar(100) COLLATE utf8_bin DEFAULT NULL,
  `date` datetime DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `idMail` (`idMail`),
  KEY `fk_type` (`type`),
  KEY `fk_idSender` (`idSender`),
  KEY `fk_senderMail` (`senderMail`),
  KEY `fk_receiverMail` (`receiverMail`),
  KEY `fk_sent` (`sent`),
  KEY `fk_reference` (`reference`),
  KEY `fk_date` (`date`)
) ENGINE=MyISAM AUTO_INCREMENT=1321784 DEFAULT CHARSET=utf8 COLLATE=utf8_bin$$

为什么“较重”的查询更快或更慢?事实上正在加载?自我线索:这一切都与 order-by 子句有关,因为如果没有日期排序,这对两者来说都快如闪电。糟糕的是,我非常需要那个日期订购。我无法通过 id 订购,因为邮件可以在未来生成,而我需要那些已经通过 NOW() 且尚未发送的邮件。

[编辑2011-04-14]

AJ 减速的正确答案可以在下面找到。我们解决这个问题的方法是创建一个连接索引,

KEY `sent` (`sent`,`date`)

解决了所有问题。

Alright, here's the deal:

I have a nice little 4Gb table called Mails on which I do the following two queries:

SELECT * FROM Mails WHERE sent = 1 ORDER BY date ASC LIMIT 600;  // 200ms
SELECT * FROM Mails WHERE sent = 0 ORDER BY date ASC LIMIT 600;  // >9000ms

The relation between sent types is following:

0    192070
1   1112341
2   11992
3   5369

The create statement is this:

CREATE TABLE `Mails` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `idMail` varchar(100) COLLATE utf8_bin NOT NULL,
  `type` varchar(100) COLLATE utf8_bin DEFAULT NULL,
  `idSender` varchar(100) COLLATE utf8_bin DEFAULT NULL,
  `senderfName` varchar(100) COLLATE utf8_bin DEFAULT NULL,
  `senderlName` varchar(100) COLLATE utf8_bin DEFAULT NULL,
  `senderMail` varchar(100) COLLATE utf8_bin DEFAULT NULL,
  `receiverMail` varchar(100) COLLATE utf8_bin DEFAULT NULL,
  `reference` varchar(100) COLLATE utf8_bin DEFAULT NULL,
  `mailContent` text COLLATE utf8_bin,
  `mailSubject` varchar(100) COLLATE utf8_bin DEFAULT NULL,
  `sent` int(1) unsigned DEFAULT '0',
  `opened` int(1) unsigned DEFAULT '0',
  `clicked` int(1) unsigned DEFAULT '0',
  `completed` int(1) unsigned DEFAULT '0',
  `abstract` varchar(100) COLLATE utf8_bin DEFAULT NULL,
  `date` datetime DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `idMail` (`idMail`),
  KEY `fk_type` (`type`),
  KEY `fk_idSender` (`idSender`),
  KEY `fk_senderMail` (`senderMail`),
  KEY `fk_receiverMail` (`receiverMail`),
  KEY `fk_sent` (`sent`),
  KEY `fk_reference` (`reference`),
  KEY `fk_date` (`date`)
) ENGINE=MyISAM AUTO_INCREMENT=1321784 DEFAULT CHARSET=utf8 COLLATE=utf8_bin$

Why the heck is the "heavier" query faster or in fact at all loading? Clues to self: It is all related to the order-by clause, because without the date ordering it's lightning fast for both. Bad thing, I need that date ordering badly. I cannot order by the id because mails can be generated into the future and I need the ones that have passed NOW() and have not been sent.

[EDIT 2011-04-14]

The correct answer to the slowdown by AJ can found below. Our solution to this problem was to create a joined index

KEY `sent` (`sent`,`date`)

Solved absolutely everything.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

可可 2024-11-08 19:28:53

使用 EXPLAIN 确定 MySQL 如何缓冲排序结果:

http:// /dev.mysql.com/doc/refman/5.1/en/using-explain.html

如果没有足够的排序缓冲区,它将使用磁盘上的临时空间,速度较慢。另请参阅调整服务器参数和myisam_sort_buffer_size

http://dev.mysql.com/doc/refman/5.1/en/server-parameters.html

Use EXPLAIN to determine how MySQL is buffering results for sorting:

http://dev.mysql.com/doc/refman/5.1/en/using-explain.html

If you don't have enough sort buffer, it will use temp space on disk, which is slower. See also Tuning Server Parameters, and myisam_sort_buffer_size:

http://dev.mysql.com/doc/refman/5.1/en/server-parameters.html

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文