I have a table for category, posts and a M2M table category_post. Here's their schema
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 ;
Here's a sample query. Usually takes about 0.60 seconds and under load as high as 3 seconds.
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
Explain:
I've been reading many references and SO posts and a bit confused about how to go about it. I'd appreciate any nod in the right direction!
I have found that if I don't include "ORDER BY pub_date DESC" the query executes in a fraction of the time. But pub_date is an index. I read somewhere that mysql will only use one index per query. Is that why it's slow?
I see that any field used in a decision context( where
, join
) have an index.
I think you should replace SELECT *
with SELECT to-be-used-column
.
Because too many columns will slow down. However it is not basic question.
Hope that it can hope you.
The solution was to perform late row lookups. More information here . Cut down execution time from 600ms to just 90ms
Here's the updated query:
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
Thank you everyone for your suggestions :)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.