我刚接触分片,想知道分片对各种查询有什么影响。对于名为“people”的样本数据集:
person_id | person_fname | person_lname | person_dob
----------------------------------------------------
1 | John | Smith | 1972-03-04
2 | Sally | Jones | 1968-09-14
3 | Phil | Forrester | 1976-11-25
4 | Gwen | Langley | 1955-04-20
5 | Pedro | Romero | 1962-12-21
6 | Gene | Halford | 1978-01-11
7 | Juan | Peza | 1977-08-07
8 | Pierre | Henry | 1980-04-30通过创建代理身份"id“的散列,在四个节点上均匀地分片数据。但是,您需要对可能跨越所有节点的记录执行读写操作,例如:
SELECT person_fname,
person_lname
FROM people
WHERE person_dob > '1970-01-01'或者假设您还有一个"orders“表,它引用了"person_id”列中的"people“,并希望执行连接...
SELECT order_id,
order_amount,
order_date,
person_fname,
person_lname
FROM orders
LEFT JOIN people
WHERE order_amount > 50实际上,所有节点都将并行运行查询吗?我假设每个服务器在每一步都会有更少的工作要做,而不是一个实例在八个记录上运行查询,同时,四个实例将在两个(Ish)记录上运行查询,进一步的好处是,如果DBMS能够执行碎片选择,那么其他节点就不需要继续执行任何进一步的指令,这个假设正确吗?
除了这个简单的例子之外,分片和复杂连接是否有任何已知的性能影响?
发布于 2012-08-28 18:33:36
它确实允许并行地完成这项工作。
如果它们必须跨越不同的分片,它确实会使连接变得复杂,因此速度会变慢。
然而,在多对一的情况下,如果您以这样一种方式进行了orders分片,即orders表中的所有行都与people表中的相关行在同一分片中,那么这种跨分片问题就不会发生。
你需要设计你的分片方法,这样你就可以得到很多这样的情况,而很少(理想情况下没有)你最终会跨越分片。
你还想把你的分片放在你实际寻找的最多的键上。例如:如果您通过用户名查找人员作为其他所有内容的起点,那么您需要按用户名而不是id进行分片,因为当找到他们时,您已经知道要命中哪个单个分片,而不是必须命中所有这些分片才能从大多数分片中取回零行。
发布于 2012-08-28 18:38:23
是的,分片带来了严重的性能变化。它从不允许应用程序保持不变。
最合理的切分方式是,如果数据模型允许真正独立地对数据进行分区。就像在多租户的情况下,租户根本不交互。在这种情况下,joins永远不会跨越分区,一切都很好。
当使用跨分区交互进行分片时,这会变得非常非常糟糕。编写一个对所有分片运行的查询的代价与分区的数量成线性关系。这意味着您可以通过添加节点来获得零加速。
发布于 2012-08-29 01:56:55
免责声明:我在ScaleBase工作,它是一个完整的横向扩展解决方案的制造商,如果你愿意,它是一个“自动切片机”,看起来和感觉上就像一个MySQL,一个“分片”网格的代理,自动化命令路由和并行化跨数据库查询,以及合并结果-你不会看到来自一个数据库的结果有什么不同。支持ORDER,GROUP,LIMIT,agg功能!路由和并行化是根据命令和参数在“控制器”中完成的。
从与我们的客户的经验来看,我们不仅在并行查询方面获得了巨大的性能改进,我们还改进了维护,考虑创建索引,向表中添加列-这些都是并行化的,运行速度也更快。对代码不做任何修改,或者修改得很少。
您的查询示例是"all-db“执行的经典示例,如果采用分布式和并行化,它们的运行速度肯定会更快。索引效率更高,使用了RAM等...
希望我能帮上忙。
https://stackoverflow.com/questions/12157026
复制相似问题