Car*_*erö 5 mysql query-optimization left-join
我有一个网站,访问者可以留下评论.我想添加回答评论的能力(即嵌套评论).
起初这个查询速度很快,但在我用现有注释(大约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
Run Code Online (Sandbox Code Playgroud)
花了2秒钟,没有儿童评论(!).
如何优化这样的查询?可能的解决方案是http://www.ferdychristant.com/blog//articles/DOMM-7QJPM7(滚动到"平板表模型完成正确")但这使分页相当困难(如何限制10个父评论1个查询内?)
该表有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 ;
Run Code Online (Sandbox Code Playgroud)
问题是,如果 MySQL 需要处理派生查询的结果,则它无法应用索引(这就是 possible_keys 列中为 NULL 的原因)。所以我建议过滤掉你需要的十条评论:
SELECT * FROM swb_comments WHERE pageId = 1411 ORDER BY id DESC LIMIT 10
Run Code Online (Sandbox Code Playgroud)
然后发送单独的请求来获取每个评论 ID 的答案:
SELECT * FROM swb_comments WHERE parentId IN ($commentId1, $commentId2, ..., $commentId10)
Run Code Online (Sandbox Code Playgroud)
在这种情况下,数据库引擎将能够有效地应用 pageId 和 ParentId 索引。