数据库缓慢检索/更新/插入问题,每个表中有超过 500 万条记录
Posted
技术标签:
【中文标题】数据库缓慢检索/更新/插入问题,每个表中有超过 500 万条记录【英文标题】:Database slow retriving/updating/inserting problem with more than 5mil records in each table 【发布时间】:2009-12-25 15:30:45 【问题描述】:如何构建数据库以避免减速? (引擎:MyISAM)
目前我在一个表中有超过 500 万条记录的数据库,这会导致数据检索缓慢。 我目前正在寻找构建数据库的方法以避免这种数据库。 (数据库引擎 MyISAM)
导致问题的表是帖子和 cmets,每个表都有超过 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
【问题讨论】:
你能提供你正在使用的数据库结构和查询吗? 你能显示 ORDER BY 子句中的内容吗? 【参考方案1】: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.id
是 PRIMARY KEY
member_extra.id
是 PRIMARY KEY
您在profile_portal.pp_member_id
上有一个索引
你也省略了ORDER BY
子句,但这个子句也很重要,使用索引也可以改进它。
【讨论】:
我在第一篇文章中添加了结构【参考方案2】:EXPLAIN PLAN 会告诉你查询引擎是如何做的。如果你看到“表扫描”,你就知道你需要索引。
【讨论】:
【参考方案3】:一张表中的 500 万行并不多,您的查询需要多长时间?我怀疑您可能对索引有一些问题。 EXPLAIN 语句可能有助于找出您的查询实际在做什么。
如果您有正确索引的表和健全的查询,您可以查看partitioning.。
编辑:
如果在表 ibf_posts 上添加 INDEX(pid, author_id) 或 INDEX(author_id, pid) 有帮助,您可以尝试。
【讨论】:
以上是关于数据库缓慢检索/更新/插入问题,每个表中有超过 500 万条记录的主要内容,如果未能解决你的问题,请参考以下文章
无法使用 pyodbc 在 Access 数据库的表中插入/更新长文本字段