我有一个类别,帖子和M2M表category_post表。这是他们的架构
CREATE TABLE IF NOT EXISTS `posts` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`title` char(255) COLLATE utf8_unicode_ci NOT NULL,
`img_url` char(255) CHARACTER SET latin1 NOT NULL,
`content` text COLLATE utf8_unicode_ci NOT NULL,
`pub_date` int(10) unsigned NOT NULL,
PRIMARY KEY (`id`),
KEY `pub_date` (`pub_date`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=42166 ;
-- --------------------------------------------------------
CREATE TABLE IF NOT EXISTS `category` (
`c_id` tinyint(3) unsigned NOT NULL AUTO_INCREMENT,
`c_name` char(255) CHARACTER SET latin1 NOT NULL,
`c_slug` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`c_active` tinyint(1) NOT NULL,
PRIMARY KEY (`c_id`),
KEY `c_slug` (`c_slug`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci COMMENT='List of Categories' AUTO_INCREMENT=47 ;
-- --------------------------------------------------------
CREATE TABLE IF NOT EXISTS `category_post` (
`cp_id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`category_id` tinyint(3) unsigned NOT NULL,
`post_id` mediumint(8) unsigned NOT NULL,
PRIMARY KEY (`cp_id`),
KEY `category_id` (`category_id`),
KEY `post_id` (`post_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=60909 ;
这是一个示例查询。通常需要大约0.60秒,负载高达3秒。
SELECT *
FROM posts p
INNER JOIN category_post cp ON p.id = cp.post_id
WHERE cp.category_id IN ( 10, 11, 12, 13, 15, 19, 33, 37, 46 )
GROUP BY id
ORDER BY pub_date DESC
LIMIT 25690 , 10
说明:
我一直在阅读很多参考资料和SO帖子,并对如何解决这个问题感到困惑。我很欣赏任何朝着正确方向的点头!
我发现如果我不包含“ORDER BY pub_date DESC”,则查询会在很短的时间内执行。但是pub_date是一个索引。我在某处读到mysql每个查询只使用一个索引。这就是为什么它很慢?
答案 0 :(得分:1)
我看到决策上下文中使用的任何字段(where
,join
)都有一个索引。
我认为您应该将SELECT *
替换为SELECT to-be-used-column
。
因为太多列会减慢速度。但这不是基本问题。
希望它能为你带来希望。
答案 1 :(得分:0)
解决方案是执行后期行查找。 More information here。将执行时间从600毫秒减少到90毫秒
这是更新的查询:
SELECT p.*
FROM (
SELECT id
FROM posts temp
INNER JOIN category_post cp ON temp.id = cp.post_id
WHERE cp.category_id IN ( 10, 11, 12, 13, 15, 19, 33, 37, 46 )
GROUP BY id
ORDER BY pub_date ASC
LIMIT 25690 , 10
) id_array
JOIN posts p ON p.id = id_array.id
ORDER BY p.pub_date ASC
谢谢大家的建议:)