【问题标题】:Restructuring a DB for best performance重构数据库以获得最佳性能
【发布时间】:2013-09-11 17:04:16
【问题描述】:

我需要一些帮助来重组我的数据库,以便以下选择查询更加高效。 问题是表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                        |
+----+-------------+---------------+------+---------------+---------+---------+--------------------+------+-----------------------------+

构建数据库以处理此任务的最佳方法是什么?

【问题讨论】:

  • 列上的任何正则表达式匹配都会使表上的任何索引变得无用,并且每个查询都需要全表扫描。

标签: mysql performance select join


【解决方案1】:

正如您自己所注意到的,这里的主要问题是类别字段的结构,导致您的语句在每次调用时都会执行全表扫描。

将其中的类别拉到另一个表中,并将其与元表粘合在一起。

首先,创建一个类别表,可能是这样的:

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 您的查询粘合在一起,完成。

【讨论】:

    猜你喜欢
    • 2019-11-24
    • 1970-01-01
    • 2013-05-07
    • 2022-01-20
    • 1970-01-01
    • 2023-03-29
    • 2018-12-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多