我需要一些帮助来重构我的数据库,以便以下选择查询更有效。
问题是表post
中的每个条目都有一个类别列,其中列表以逗号分隔。
查询
SELECT id, short_story, SUBSTRING( full_story, 1, 15 ) AS full_story, xfields, title, category, alt_name, comm_num, allow_comm, allow_rate,
FIXED , rating, vote_num, news_read, votes, editdate, editor, reason, view_edit, tags
FROM post
LEFT JOIN post_plus ON ( post.id = post_plus.news_id )
WHERE category REGEXP '[[:<:]](130|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|21|22|24|25|26|27|29|133|135|125|20|132)[[:>:]]'
AND category REGEXP '[[:<:]](73)[[:>:]]'
AND approve =1
ORDER BY FIXED DESC , DATE DESC
LIMIT 98 , 7
列表太长了,因为我有几个主要类别和许多子类别。目前它用ragexp扫描整个表并搜索正确的匹配。当我检查process list
时,我看到大量上述查询的状态为Creating sort index
且我的cpu是100%使用
解释表明我正在使用正确的索引:
+----+-------------+---------------+------+---------------+---------+---------+--------------------+------+-----------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------------+------+---------------+---------+---------+--------------------+------+-----------------------------+
| 1 | SIMPLE | post | ref | approve | approve | 1 | const | 9593 | Using where; Using filesort |
| 1 | SIMPLE | post_plus | ref | news_id | news_id | 5 | online.post.id | 1 | NULL |
+----+-------------+---------------+------+---------------+---------+---------+--------------------+------+-----------------------------+
构建数据库以处理此任务的最佳方法是什么?
答案 0 :(得分:1)
正如您已经注意到的那样,这里的主要问题是类别字段的结构,导致您的语句在每次调用时执行全表扫描。
将那里的类别ouf拉到另一个表中,然后用元表将它粘合在一起。
首先,创建一个类别表,可能是这样的:
CREATE TABLE `post_category_meta` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`post_id` bigint(20) unsigned NOT NULL,
`category_id` bigint(20) unsigned NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM
现在创建一个元表:
CREATE TABLE `post_category_meta` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`post_id` bigint(20) unsigned NOT NULL,
`category_id` bigint(20) unsigned NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `meta` (`post_id`,`category_id`),
KEY `post_id` (`post_id`),
KEY `category_id` (`category_id`)
) ENGINE=MyISAM
现在将您的类别添加到类别表中,并在元表中添加关系。使用正确的JOIN
查询将它们粘贴在一起,完成。