【发布时间】:2010-07-18 09:12:36
【问题描述】:
我有一个网站,访问者可以在其中离开 cmets。我想添加回答 cmets 的能力(即嵌套 cmets)。
起初这个查询很快,但在我用现有的 cmets(大约 30000 个)填充表后,一个简单的查询如下:
SELECT c.id, c2.id
FROM (SELECT id
FROM swb_comments
WHERE pageId = 1411
ORDER BY id DESC
LIMIT 10) AS c
LEFT JOIN swb_comments AS c2 ON c.id = c2.parentId
超过 2 秒,没有 childComments(!)。
如何优化这样的查询?可能的解决方案是http://www.ferdychristant.com/blog//articles/DOMM-7QJPM7(滚动到“正确完成的平面表模型”),但这使得分页相当困难(如何在 1 个查询中限制为 10 个父 cmets?)
该表有 3 个索引,id、pageId 和 ParentId。
提前致谢!
编辑:
添加了表定义。这是与上述 SELECT 查询有些不同的完整定义(即 pageId 而不是 numberId 以避免混淆)
CREATE TABLE `swb_comments` (
`id` mediumint(9) NOT NULL auto_increment,
`userId` mediumint(9) unsigned NOT NULL default '0',
`numberId` mediumint(9) unsigned default NULL,
`orgId` mediumint(9) unsigned default NULL,
`author` varchar(100) default NULL,
`email` varchar(255) NOT NULL,
`message` text NOT NULL,
`IP` varchar(40) NOT NULL,
`timestamp` varchar(25) NOT NULL,
`editedTimestamp` varchar(25) default NULL COMMENT 'last edited timestamp',
`status` varchar(20) NOT NULL default 'publish',
`parentId` mediumint(9) unsigned NOT NULL default '0',
`locale` varchar(10) NOT NULL,
PRIMARY KEY (`id`),
KEY `userId` (`userId`),
KEY `numberId` (`numberId`),
KEY `orgId` (`orgId`),
KEY `parentId` (`parentId`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=34748 ;
【问题讨论】:
-
您打算无限嵌套吗? (即,您可以再次回复答案?)或者只有一级深度最大值?
-
EXPLAIN 有什么要说的?
-
SELECT id FROM swb_cmets WHERE pageId = 1411 LIMIT 10 也慢吗?您从父 ID 加入获得了多少点击?
-
如果子选择中没有 ORDER BY,您实际上是在随机选择 cmets。这是本意吗?
-
@Daniel 我只想要一个级别(Facebook 风格)。 @Sam SELECT id FROM swb_cmets WHERE numberId =1411 ORDER BY id DESC LIMIT 10 只有 0.0024 秒,所以没有。目前我只从旧表中导入了所有行,所以根本没有子 cmets。 @Marcelo 感谢您的订购,被切成 0.2 秒,这很棒。我更新了问题以包含它。
标签: mysql query-optimization left-join