我有3个表格 - 职位,posts_groups和组与帖子和组之间MANY_2_MANY关系。为了获得来自特定组的所有帖子,我需要加入帖子和posts_groups表。现在加入非常缓慢。我在这里描述了非常相似的情况MySQL JOIN/IN performance optimizationMysql非规范化连接表与many_2_many
我认为,为了提高性能,我需要对此结构进行非规范化。 MySQL的最佳做法是什么?我可以为帖子创建一个新的表格,我会为这些帖子参与的群组设置一些散列吗?基于这个散列,我将能够通过单选来查询来自特定组的所有帖子。如果不是的话,你能否建议最合适的方法来改善这种结构的性能?
修订
示例查询:
SELECT p.post_id, p.date_created, p.description, p.last_edited,
p.link, p.link_description, p.link_image_url, p.link_title,
p.total_comments, p.total_votes, p.type_id, p.user_id
FROM posts p
JOIN
(SELECT DISTINCT post_id
FROM posts_to_groups
WHERE group_id IN (1, 2, 3, 4, 5)
) AS ptt USING (post_id)
ORDER BY p.last_edited DESC,
p.total_votes DESC
LIMIT 25
此查询的工作快只在非并发环境 - 〜150ms的。在约50个并发用户的性能测试(JMeter)下,它显示5秒。
CREATE TABLE:
CREATE TABLE `posts` (
`post_id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` varchar(255) NOT NULL,
`type_id` int(11) NOT NULL,
`description` text,
`link` varchar(1024) DEFAULT NULL,
`date_created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`last_edited` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`total_votes` int(11) DEFAULT '0',
`total_comments` int(11) DEFAULT '0',
`link_title` varchar(1024) DEFAULT NULL,
`link_description` varchar(1024) DEFAULT NULL,
`link_image_url` varchar(1024) DEFAULT NULL,
PRIMARY KEY (`post_id`),
KEY `fk_post_type_id` (`type_id`),
FULLTEXT KEY `description` (`description`),
CONSTRAINT `fk_post_type_id` FOREIGN KEY (`type_id`) REFERENCES `post_types` (`post_type_id`)
)
ENGINE=InnoDB AUTO_INCREMENT=109919 DEFAULT CHARSET=utf8
CREATE TABLE `posts_to_groups` (
`group_id` int(11) NOT NULL,
`post_id` int(11) NOT NULL,
PRIMARY KEY (`group_id`,`post_id`),
KEY `post_to_groups_fk_post_id` (`post_id`),
CONSTRAINT `post_to_groups_fk_post_id` FOREIGN KEY (`post_id`) REFERENCES `posts` (`post_id`),
CONSTRAINT `post_to_groups_fk_group_id` FOREIGN KEY (`group_id`) REFERENCES `groups` (`group_id`)
)
ENGINE=InnoDB DEFAULT CHARSET=utf8
CREATE TABLE `groups` (
`group_id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` varchar(255) NOT NULL,
`title` varchar(255) NOT NULL,
`description` text NOT NULL,
`date_created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`total_members` int(11) NOT NULL DEFAULT '0',
`total_posts` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`group_id`),
KEY `user_id_idx` (`user_id`),
FULLTEXT KEY `title` (`title`,`description`)
)
ENGINE=InnoDB AUTO_INCREMENT=1288 DEFAULT CHARSET=utf8
我们有很多的关系(Many_2_Many)和它的工作速度快,你对这些表的索引?并且您可以添加您的查询,我们会查找它 –
确保您的查询正在使用**适当的索引**。很可能,您的查询可以从覆盖索引或多列索引中受益。 (“在每个单独的列上添加索引”很少是最合适的方法。) – spencer7593
我更新了我的问题。另外,我有所有索引那里,细节在这里http://stackoverflow.com/questions/30872163/mysql-join-in-performance-optimization – alexanoid