假设我有一张桌子
id col1 col2 col3 1 ABC DEF XYZ 2 XXX YYY ZZZ
最常见的查询将是
SELECT * from XYZ where col1='abc' and col2='def'
SELECT * from XYZ where col1='abc' and col2='def' and col3='xyz'
根据VoltDB文档: -
我找不到任何在多列上执行搜索的示例。
我想知道为多列搜索分区表的最佳方法是什么?
编辑: -
或者如果我的查询是这样的: -
SELECT * from XYZ where col1 IN ('abc', ..., ...) and col2 IN ('def', ...) and col3 IN ('xyz', ...).
答案 0 :(得分:4)
挑选专栏的指南:
首先,您应该选择具有许多不同值的分区列。为了说明这一点,如果你有两个以上的分区(常见),那么选择一个男/女专栏的分区很差。
选择一个具有一些主导其他值的值的列也是一个坏主意。如果20%的值为NULL,则超过20%的行将分区到同一位置。分配不必是均匀的,但如果你有" hot"价值观,它至少有更多的帮助" hot"值而不是分区。
如果时间戳的进展速度低于摄取速度,那么选择时间戳也会很棘手。在这种情况下,当时间戳推进时,您的负载将一次一个地循环分区。虽然在实践中,单个分区通常每秒可处理10-50k个插件,因此这实际上适用于非特殊用例。
因此,如果对具有大量均匀分布的值的列进行分区,则插入将很好地分区,并且您将能够摄取一些严重的负载。
选择专栏以优化查询:
现在问题变成,给定一组候选列,您可以选择一个以使查询运行得更快吗?
可以将与分区列的相等性测试匹配的任何查询发送到单个分区。在上面的示例中,如果您在col1或col2上进行了分区,则两个查询都将是单个分区。如果您在col3上进行了分区,则只有第二个查询将是单一分区的。
很多时候,分区列很明显,可能是客户ID或票证符号。但即使它很明显,特别是如果不是这样,你也会想要运行不分区的查询。好消息是VoltDB 4.0使得只读的跨分区查询比以前的版本快得多。我们的内部基准测试表明,每秒可以进行数万次查询。
此级别的跨分区读取性能通常优于非分区RDBMS的读取性能。所以在VoltDB 4.0中,分区写操作比读操作更重要。这使分区更简单。
答案 1 :(得分:0)
以下是一些可能有助于选择分区列的标准:
基本考虑因素:
应该具有足够基数的值,以便它使用所有分区
理想情况下,值应均匀散列,以便分配到分区。
这可能会给你留下几个选择。如果工作负载主要是插入,则任何都可以,因为插入将始终提供分区列值,因此插入将始终在单个分区中执行,因此可以很好地扩展。要确定哪个列最佳,您可以考虑:
对于查询和其他事务,哪一列最常作为输入参数提供?
如果有涉及多个表的事务,哪个列由所有相关表共享?
如果您需要将表与另一个分区表连接,则必须对其中一个连接键进行分区。
希望这能说清楚什么是最好的选择。可以进行权衡,因此有时候测试不同的方法是值得的。有时,为了提供相关表的公共分区键,可能会略微进行非规范化,这可能会导致单个分区事务的百分比更高,或者启用更多连接。此外,将查询作为多分区事务运行也是完全可以的。这些可以扩展到每秒数千,在某些情况下可以达到每秒数千。因此,虽然您确实想要最大化单分区工作负载的百分比,但您仍然可以使用不是百分比。
索引也非常重要。在您的示例中,如果您选择col1或col2,则两个查询都将作为单分区事务执行,但在单分区内可能会有许多具有不同分区键值的记录。将列定义为分区键不会自动在该列上创建索引。您仍然希望定义索引以支持您需要快速且经常执行的查询。 VoltDB是一个行存储,因此在传统RDBMS上创建索引时将使用许多相同的注意事项。根据示例查询,(col1,col2,col3)上的索引将支持两个查询。如果您有许多需要经常运行的不同搜索查询,则可能有助于创建多个索引。
在设计索引时,有助于检查查询的解释计划。您可以使用以下命令在VoltDB的SQL界面中执行此操作: https://voltdb.com/docs/UsingVoltDB/sysprocexplain.php https://voltdb.com/docs/UsingVoltDB/...xplainproc.php
您还可以在运行“voltdb compile”时输出的html目录报告中看到这些解释计划。目录报告也可通过端口8080上的Web界面获得。
该计划将显示查询执行是否涉及表扫描,或者它是否将使用索引。