- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
有一个大数据库,有 1,000,000,000 行,称为线程(这些线程确实存在,我并不是因为我喜欢它而使事情变得更难)。 Threads 里面只有一些东西,让事情变得更快:(int id, string hash, int replycount, int dateline (timestamp), int forumid, string title)
查询:
select * from thread where forumid = 100 and replycount > 1 order by dateline desc limit 10000, 100
因为有 1G 的记录,所以查询速度很慢。所以我想,让我们将这 1G 的记录拆分到我拥有的论坛(类别)中尽可能多的表中!这几乎是完美的。有很多表,我搜索的记录较少,而且速度真的更快。查询现在变为:
select * from thread_{forum_id} where replycount > 1 order by dateline desc limit 10000, 100
这对于 99% 的论坛(类别)来说确实更快,因为其中大多数只有少数主题 (100k-1M)。但是,因为有些记录有大约 10M 的记录,所以一些查询仍然很慢(0.1/.2 秒,对我的应用程序来说太慢了!我已经在使用索引了!强>)。
我不知道如何使用 MySQL 来改进这一点。有什么办法吗?
对于这个项目,我将使用 10 台服务器(12GB 内存,软件 raid 10 上的 4x7200rpm 硬盘,四核)
这个想法是在服务器之间简单地拆分数据库,但是上面解释的问题仍然不够。
如果我在这 10 台服务器上安装 cassandra(假设我有时间让它按预期工作),我是否应该假设性能提升?
我该怎么办?继续使用 MySQL 在多台机器上使用分布式数据库或构建 cassandra 集群?
我被要求发布索引是什么,它们是:
mysql> show index in thread;
PRIMARY id
forumid
dateline
replycount
选择解释:
mysql> explain SELECT * FROM thread WHERE forumid = 655 AND visible = 1 AND open <> 10 ORDER BY dateline ASC LIMIT 268000, 250;
+----+-------------+--------+------+---------------+---------+---------+-------------+--------+-----------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+--------+------+---------------+---------+---------+-------------+--------+-----------------------------+
| 1 | SIMPLE | thread | ref | forumid | forumid | 4 | const,const | 221575 | Using where; Using filesort |
+----+-------------+--------+------+---------------+---------+---------+-------------+--------+-----------------------------+
最佳答案
您应该阅读以下内容并了解一些关于精心设计的 innodb 表的优势以及如何最好地使用聚集索引 - 仅适用于 innodb!
http://dev.mysql.com/doc/refman/5.0/en/innodb-index-types.html
http://www.xaprb.com/blog/2006/07/04/how-to-exploit-mysql-index-optimizations/
然后按照以下简化示例设计您的系统:
重要的特点是表使用innodb引擎,thread表的主键不再是单个auto_incrementing键,而是基于forum_id和thread_id组合的复合clustered键。例如
threads - primary key (forum_id, thread_id)
forum_id thread_id
======== =========
1 1
1 2
1 3
1 ...
1 2058300
2 1
2 2
2 3
2 ...
2 2352141
...
每个论坛行都包含一个名为 next_thread_id (unsigned int) 的计数器,该计数器由触发器维护,并在每次将线程添加到给定论坛时递增。这也意味着如果对 thread_id 使用单个 auto_increment 主键,我们每个论坛可以存储 40 亿个线程,而不是总共 40 亿个线程。
forum_id title next_thread_id
======== ===== ==============
1 forum 1 2058300
2 forum 2 2352141
3 forum 3 2482805
4 forum 4 3740957
...
64 forum 64 3243097
65 forum 65 15000000 -- ooh a big one
66 forum 66 5038900
67 forum 67 4449764
...
247 forum 247 0 -- still loading data for half the forums !
248 forum 248 0
249 forum 249 0
250 forum 250 0
使用复合键的缺点是不能再通过单个键值来选择线程,如下:
select * from threads where thread_id = y;
你必须做的:
select * from threads where forum_id = x and thread_id = y;
但是,您的应用程序代码应该知道用户正在浏览哪个论坛,因此实现起来并不困难 - 将当前查看的 forum_id 存储在 session 变量或隐藏表单字段等中......
这是简化的架构:
drop table if exists forums;
create table forums
(
forum_id smallint unsigned not null auto_increment primary key,
title varchar(255) unique not null,
next_thread_id int unsigned not null default 0 -- count of threads in each forum
)engine=innodb;
drop table if exists threads;
create table threads
(
forum_id smallint unsigned not null,
thread_id int unsigned not null default 0,
reply_count int unsigned not null default 0,
hash char(32) not null,
created_date datetime not null,
primary key (forum_id, thread_id, reply_count) -- composite clustered index
)engine=innodb;
delimiter #
create trigger threads_before_ins_trig before insert on threads
for each row
begin
declare v_id int unsigned default 0;
select next_thread_id + 1 into v_id from forums where forum_id = new.forum_id;
set new.thread_id = v_id;
update forums set next_thread_id = v_id where forum_id = new.forum_id;
end#
delimiter ;
您可能已经注意到我将 reply_count 作为主键的一部分包含在内,这有点奇怪,因为 (forum_id, thread_id) 组合本身是唯一的。这只是一个索引优化,它在执行使用 reply_count 的查询时节省了一些 I/O。有关更多信息,请参阅上面的 2 个链接。
我仍在将数据加载到我的示例表中,到目前为止,我已经加载了大约。 5 亿行(是您系统的一半)。加载过程完成后,我应该期望有大约:
250 forums * 5 million threads = 1250 000 000 (1.2 billion rows)
我故意让一些论坛的帖子数超过 500 万,例如,论坛 65 有 1500 万个帖子:
forum_id title next_thread_id
======== ===== ==============
65 forum 65 15000000 -- ooh a big one
select sum(next_thread_id) from forums;
sum(next_thread_id)
===================
539,155,433 (500 million threads so far and still growing...)
在 innodb 下对 next_thread_ids 求和以给出总线程数比平时快得多:
select count(*) from threads;
论坛65有多少个话题:
select next_thread_id from forums where forum_id = 65
next_thread_id
==============
15,000,000 (15 million)
这再次比平常更快:
select count(*) from threads where forum_id = 65
好的,现在我们知道到目前为止我们有大约 5 亿个线程,论坛 65 有 1500 万个线程 - 让我们看看架构如何执行 :)
select forum_id, thread_id from threads where forum_id = 65 and reply_count > 64 order by thread_id desc limit 32;
runtime = 0.022 secs
select forum_id, thread_id from threads where forum_id = 65 and reply_count > 1 order by thread_id desc limit 10000, 100;
runtime = 0.027 secs
对我来说看起来非常高效 - 所以这是一个包含 500+ 百万行(并且还在增长)的单个表,其查询在 0.02 秒内覆盖了 1500 万行(在负载下!)
这些将包括:
按范围分区
分片
投入金钱和硬件
等等……
希望这个答案对您有所帮助:)
关于php - MySQL 和 NoSQL : Help me to choose the right one,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4419499/
在大规模数据集(Google,Facebook,linkedin)中使用非关系数据库(例如键值对存储)的好处显而易见。您认为中小型应用程序如何从使用非关系数据库中受益? 最佳答案 自60年代以来,IB
我正在努力弄清楚如何最好地为我的系统实现这一点……现在让我的头离开 RDBMS 空间…… 我当前数据库的一部分有三个表:Show、ShowEntry 和 Entry。 ShowEntry 基本上是 S
我计划使用 nosql 数据库作为我的 Web 产品的后端。我有几个非常基本的疑问。 1) 我在博客中读到 Nosql 数据库对于在线货币交易不太好,即数据完整性是最重要的。(我的产品有在线货币交易)
关闭。这个问题是opinion-based .它目前不接受答案。 想改善这个问题吗?更新问题,以便可以通过 editing this post 用事实和引文回答问题. 去年关闭。 Improve th
关闭。这个问题是opinion-based 。目前不接受答案。 想要改进这个问题吗?更新问题,以便 editing this post 可以用事实和引文来回答它。 . 已关闭 9 年前。 Improv
NoSQL 术语有 4 个类别。 键\值存储 面向文档 图 面向列。 从我的角度来看,所有这些数据建模都有相同的定义,有什么区别? Key\value 数据库以类似 OOP 中的对象的结构维护数据。访
我正在做一个小项目,我需要构建一个倒排索引并应用基于用户查询的相似性算法 - 基本信息检索。构建和搜索倒排索引的最佳 NoSQL 产品是什么? 谢谢,J 最佳答案 由于倒排索引是关于存储单词与其在文档
关闭。这个问题是opinion-based .它目前不接受答案。 想改进这个问题?更新问题,以便 editing this post 可以用事实和引用来回答它. 8年前关闭。 Improve this
当使用SQL数据库时,有不同的方式来显示系统的流程。在银行中,您可以使用 ER 来显示其属性。并为其操作使用类图 UML。 有什么更好的方法可以为最终用户表示 NoSQL 数据库,如果有任何图表我可以
关系数据库使用键来完成,并且发生在 (a 非常令人放心的 ) 数据级别。文档数据库必须在应用程序级别强制执行。 RDB 确实强制执行参照完整性。如果两个人之间的关系,如果一个人被删除,关系将自动不复存
我目前正在尝试实现类似 Tumblr 的用户交互,例如转发、关注、关注者、评论、我当前关注的人的博客文章等。 还需要显示每篇博客文章的事件。 我坚持为数据库创建适当的架构。有几种方法可以实现这种功能(
我一直在对 Nosql(尤其是 RavenDB)进行一些研究,但我仍然不确定处理以下问题的最佳方法: 我有两个简单的对象,“用户”和“事件”。一个用户可以输入多个事件,一个事件可以由多个用户输入——标
刚刚看到这篇关于 NOSQL 模式的文章(不是我的)。从开发人员的角度来看,它涵盖了许多 NOSQL 实现模式(如散列和复制模式)。 总而言之,如果有人问自己这个问题,它非常有用: Where can
我现在在网上听到了很多关于 nosql 键/值数据库的信息。你能举个例子说明一个是做什么用的。什么样的真实世界数据最适合这类数据库? 最佳答案 我认为'What the heck are you ac
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引起辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the he
我目前正在从事一个项目,其中包括出于性能原因将内容推荐器从 MySQL 迁移到 NoSQL 数据库。我们的团队一直在评估一些替代方案,例如 MongoDB、CouchDB、HBase 和 Cassan
我们正在为即将到来的项目评估 NoSQL。我倾向于以 RDBMS 的方式思考问题,并且在概念化缺乏规范化方面遇到了困难。 我知道在 NoSQL 中复制数据不被认为是错误的。我无法理解的是修复数据更改以
有人建议我研究键/值对数据系统来替换我一直在使用的关系数据库。 我不太了解的是这如何提高查询效率。据我了解,您将丢弃大量有助于提高查询效率的信息,只需将您的结构数据库变成一个长长的键和值列表? 我完全
我正在尝试找出 NoSQL KVP 或文档数据库中外键和索引的等效项。由于没有数据透视表(用于添加标记两个对象之间关系的键),我真的很困惑如何以对普通网页有用的方式检索数据。 假设我有一个用户,该用户
我打算开始学习 NoSQL。我是从《Professional NoSQL》这本书开始的。书中有使用 CouchDB、Cassandra、MongoDB 等的示例。我的疑问是我应该安装所有不同的风格来完
我是一名优秀的程序员,十分优秀!