每个表中超过 500 万条记录时数据库缓慢检索/更新/插入问题

发布于 2024-08-15 14:00:00 字数 2386 浏览 8 评论 0原文

如何构建数据库以避免速度变慢? (引擎:MyISAM)

目前我的数据库一张表中有超过500万条记录,导致数据检索缓慢。 我目前正在寻找构建数据库的方法以避免此类数据库。 (数据库引擎 MyISAM)

导致问题的表是每个帖子和评论的记录超过 500 万条。

我有一个想法,在按日期保存记录时使用文本文件作为存储,以便每个文件包含足够的数据,不会减慢检索和保存过程,但对于数据库,我不知道该怎么办:(

有什么办法吗在 MySQL 数据库中保存数据(每个大约 500 万条记录)不会导致检索、插入或更新数据缓慢?

结构

    CREATE TABLE IF NOT EXISTS `ibf_posts` (
  `pid` int(10) NOT NULL auto_increment,
  `append_edit` tinyint(1) default '0',
  `edit_time` int(10) default NULL,
  `author_id` mediumint(8) NOT NULL default '0',
  `author_name` varchar(32) default NULL,
  `use_sig` tinyint(1) NOT NULL default '0',
  `use_emo` tinyint(1) NOT NULL default '0',
  `ip_address` varchar(16) default NULL,
  `post_date` int(10) default NULL,
  `icon_id` smallint(3) default NULL,
  `post` text,
  `queued` tinyint(1) NOT NULL default '0',
  `topic_id` int(10) NOT NULL default '0',
  `post_title` varchar(255) default NULL,
  `new_topic` tinyint(1) default '0',
  `edit_name` varchar(255) default NULL,
  `post_key` varchar(32) default NULL,
  `post_parent` int(10) NOT NULL default '0',
  `post_htmlstate` smallint(1) NOT NULL default '0',
  `post_edit_reason` varchar(255) default NULL,
  PRIMARY KEY  (`pid`),
  KEY `topic_id` (`topic_id`,`queued`,`pid`,`post_date`),
  KEY `author_id` (`author_id`,`topic_id`),
  KEY `post_date` (`post_date`),
  KEY `ip_address` (`ip_address`),
  KEY `post_key` (`post_key`),
  FULLTEXT KEY `post` (`post`),
  FULLTEXT KEY `post_2` (`post`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8;

查询:

SELECT p.*, pp.*,.id,m.name,m.mgroup,m.email,m.joined,m.posts, m.last_visit, m.last_activity,m.login_anonymous,m.title,m.hide_email, m.warn_level, m.warn_lastwarn, m.points, m.topics_started, m.skin,
                    me.msnname,me.aim_name,me.icq_number,me.signature, me.website,me.yahoo,me.location, me.avatar_location, me.avatar_type, me.avatar_size, m.members_display_name, m.custom_post_css, m.custom_right_img
                    m.custom_post_color
                        FROM posts p
                            LEFT JOIN members m ON (m.id=p.author_id)
                            LEFT JOIN profile_portal pp ON (m.id=pp.pp_member_id)
                            LEFT JOIN member_extra me ON (me.id=m.id)
                        WHERE p.pid IN(--post ids here) 
                        ORDER BY --ordering here

How to structure database to avoid slowdowns? (Engine: MyISAM)

Currently i have database with more than 5milion records in one table that causes slow data retrieving.
I'm currently searching for ways to structure database to avoid this kinds of database. (Database Engine MyISAM)

Tables that cause problems are posts and comments having more than 5mil records in each.

I had an idea when using text file as storage when saving records by date, so that each file contained enough data that wasn't slowing retrieving and saving processes, But with databases i don't know what to do :(

Is there any way to save data (approx 5mil records in each) in MySQL database not to cause slow retrieving, inserting or updating data?

"posts" Structure

    CREATE TABLE IF NOT EXISTS `ibf_posts` (
  `pid` int(10) NOT NULL auto_increment,
  `append_edit` tinyint(1) default '0',
  `edit_time` int(10) default NULL,
  `author_id` mediumint(8) NOT NULL default '0',
  `author_name` varchar(32) default NULL,
  `use_sig` tinyint(1) NOT NULL default '0',
  `use_emo` tinyint(1) NOT NULL default '0',
  `ip_address` varchar(16) default NULL,
  `post_date` int(10) default NULL,
  `icon_id` smallint(3) default NULL,
  `post` text,
  `queued` tinyint(1) NOT NULL default '0',
  `topic_id` int(10) NOT NULL default '0',
  `post_title` varchar(255) default NULL,
  `new_topic` tinyint(1) default '0',
  `edit_name` varchar(255) default NULL,
  `post_key` varchar(32) default NULL,
  `post_parent` int(10) NOT NULL default '0',
  `post_htmlstate` smallint(1) NOT NULL default '0',
  `post_edit_reason` varchar(255) default NULL,
  PRIMARY KEY  (`pid`),
  KEY `topic_id` (`topic_id`,`queued`,`pid`,`post_date`),
  KEY `author_id` (`author_id`,`topic_id`),
  KEY `post_date` (`post_date`),
  KEY `ip_address` (`ip_address`),
  KEY `post_key` (`post_key`),
  FULLTEXT KEY `post` (`post`),
  FULLTEXT KEY `post_2` (`post`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8;

Query:

SELECT p.*, pp.*,.id,m.name,m.mgroup,m.email,m.joined,m.posts, m.last_visit, m.last_activity,m.login_anonymous,m.title,m.hide_email, m.warn_level, m.warn_lastwarn, m.points, m.topics_started, m.skin,
                    me.msnname,me.aim_name,me.icq_number,me.signature, me.website,me.yahoo,me.location, me.avatar_location, me.avatar_type, me.avatar_size, m.members_display_name, m.custom_post_css, m.custom_right_img
                    m.custom_post_color
                        FROM posts p
                            LEFT JOIN members m ON (m.id=p.author_id)
                            LEFT JOIN profile_portal pp ON (m.id=pp.pp_member_id)
                            LEFT JOIN member_extra me ON (me.id=m.id)
                        WHERE p.pid IN(--post ids here) 
                        ORDER BY --ordering here

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

命比纸薄 2024-08-22 14:00:00

5M 并不算多。

可能您对表的索引错误。

请发布您的疑问,我们可能会告诉您如何改进它。

更新:

SELECT  p.*, pp.*,.id,m.name,m.mgroup,m.email,m.joined,m.posts, m.last_visit, m.last_activity,m.login_anonymous,m.title,m.hide_email, m.warn_level, m.warn_lastwarn, m.points, m.topics_started, m.skin,
        me.msnname,me.aim_name,me.icq_number,me.signature, me.website,me.yahoo,me.location, me.avatar_location, me.avatar_type, me.avatar_size, m.members_display_name, m.custom_post_css, m.custom_right_img
        m.custom_post_color
FROM    posts p
LEFT JOIN
        members m
ON      m.id = p.author_id 
LEFT JOIN
        profile_portal pp
ON      pp.pp_member_id = m.id
LEFT JOIN
        member_extra me
ON      me.id = m.id
WHERE   p.pid IN (--post ids here) 
ORDER BY
        --ordering here

确保:

  • members.idPRIMARY KEY
  • member_extra.idPRIMARY KEY
  • 您在 profile_portal.pp_member_id 上有一个索引。

您还省略了 ORDER BY 子句,但该子句也很重要,使用索引也可以改进它。

5M is not that much.

Probably you indexed the table wrong.

Please post your query and we'll probably tell you how to improve it.

Update:

SELECT  p.*, pp.*,.id,m.name,m.mgroup,m.email,m.joined,m.posts, m.last_visit, m.last_activity,m.login_anonymous,m.title,m.hide_email, m.warn_level, m.warn_lastwarn, m.points, m.topics_started, m.skin,
        me.msnname,me.aim_name,me.icq_number,me.signature, me.website,me.yahoo,me.location, me.avatar_location, me.avatar_type, me.avatar_size, m.members_display_name, m.custom_post_css, m.custom_right_img
        m.custom_post_color
FROM    posts p
LEFT JOIN
        members m
ON      m.id = p.author_id 
LEFT JOIN
        profile_portal pp
ON      pp.pp_member_id = m.id
LEFT JOIN
        member_extra me
ON      me.id = m.id
WHERE   p.pid IN (--post ids here) 
ORDER BY
        --ordering here

Make sure that:

  • members.id is a PRIMARY KEY
  • member_extra.id is a PRIMARY KEY
  • You have an index on profile_portal.pp_member_id

Also you omitted the ORDER BY clause but this clause is important too, using indexes can improve it as well.

满身野味 2024-08-22 14:00:00

EXPLAIN PLAN 将告诉您查询引擎是如何执行此操作的。如果您看到“表扫描”,则说明您需要索引。

EXPLAIN PLAN will tell you how the query engine is doing it. If you see "table scan", you know you need indexes.

老娘不死你永远是小三 2024-08-22 14:00:00

一张表中的 5M 行并不算多,您的查询需要多长时间?我怀疑您可能在索引方面遇到一些问题。 EXPLAIN 语句可能有助于找出您查询的内容实际上正在做。

如果您有正确索引的表和合理的查询,您可以查看 分区。

编辑:

您可以尝试在表 ibf_posts 上添加 INDEX(pid,author_id) 或 INDEX(author_id,pid) 是否有帮助。

5M rows in one table is not that much, how long your queries are taking? I suspect you may have some problems with indexing. EXPLAIN statement may help to find out what you queries are actually doing.

If you have properly indexed tables and sane queries, you could look into partitioning..

Edit:

You could try if adding INDEX(pid, author_id) or INDEX(author_id, pid) on table ibf_posts helps.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文