在MySql InnoDB中,与仅使用索引相比,是否存在分区表的性能优势?
答案 0 :(得分:1)
常见考虑事项:
索引并不总是正确的工具。在高级别,请记住索引是最多的 当他们帮助存储引擎找到行而不添加更多工作时有效 他们避免。对于非常小的表,简单地读取所有行通常更有效 在表中。对于中型到大型表,索引可以非常有效。对于巨大的 表,索引的开销,以及实际使用索引所需的工作, 可以开始加起来。在这种情况下,您可能需要选择一种识别技术 查询感兴趣的行组,而不是单个行。您可以 为此目的使用分区。指数是最佳解决方案吗?
如果你有很多表,那么创建一个元数据表来存储一些表也是有意义的 您的查询感兴趣的特征。例如,如果您执行查询 在数据被分区的多租户应用程序中对行执行聚合 在许多表中,您可以记录系统中哪些用户实际存储在每个表中 table,因此您可以忽略那些没有相关信息的表 用户。这些策略通常只在非常大的范围内有用。实际上,这是一个 Infobright所做的粗略近似。在太字节的规模,定位单个行是没有意义的;索引由每块元数据替换。 有一件事是肯定的:每次要查询时都无法扫描整个表格, 因为它太大了而且由于维护,您不希望使用索引 成本和空间消耗。根据索引,您可能会获得大量碎片和数据不佳的数据,这将导致数千次切入导致死亡 随机I / O.您有时可以解决一个或两个索引,但很少 更多。只剩下两个可行的选项:您的查询必须是顺序扫描 在表格的一部分上,或表格和索引的所需部分必须完全适合 在记忆中。
值得重申的是:在非常大的尺寸下,B-Tree索引不起作用。除非索引 完全覆盖查询,服务器需要查找表中的完整行,并且 这会导致一个非常大的空间上一次一行的随机I / O,这只会导致查询失败 响应时间。维护索引(磁盘空间,I / O操作)的成本也是 很高。诸如Infobright之类的系统承认这一点并抛出B-Tree索引 完全地,选择粗粒度但成本较低的东西,例如每块 大数据块上的元数据。
这也是分区可以实现的目标。关键是要考虑分区 作为索引的粗略形式,具有非常低的开销,并让你在附近 你想要的数据。从那里,您可以按顺序扫描邻域, 或者将邻居放在记忆中并将其编入索引。分区的开销很低,因为 没有指向行的数据结构,必须更新分区 不以行的精度标识数据,并且没有数据结构可言。 相反,它有一个方程式,说明哪些分区可以包含哪些类别 行。
(非常感谢 高性能MySQL 好书)
答案 1 :(得分:0)
我查看过的99%的案例都没有从PARTITIONing
那里受益INDEXing
。
我使用分区的经验法则在http://mysql.rjweb.org/doc.php/partitionmaint。此外,它还列出了仅 4个用例,其中分区提高了性能。
好吧,我不能说“完全”99%,但它非常接近。我确实相信“4” - 我一直在寻找,因为多年前分区被添加到MySQL。
对于数据仓库,通常的性能解决方案是创建和维护“汇总表”。这适用于“大多数”DW应用程序。
“非常大的BTree不起作用”?公牛。一百万行索引的BTree深度约为3.万亿行 - 约为6.哪里“不行”?万亿行表上的“点查询”将触及BTree中两倍的节点,并且更多的节点不可能被缓存。但它“会奏效”。
Infobright凭借其“柱状存储”有其利基。具有“分形索引”的TokuDB有其利基。没有人可以说“我们当时比BTree 大多数更好”。 (这些引擎都通过压缩获得了部分速度。)
底线:使用索引。可能是一个“复合”指数。 (更多索引提示:http://mysql.rjweb.org/doc.php/index_cookbook_mysql)