首页 > 解决方案 > Mariadb 扫描时间戳列中的所有分区

问题描述

我有一个表分区:

HASH(timestamp DIV 43200 )

当我执行此查询时

SELECT max(id) 
  FROM messages 
 WHERE timestamp BETWEEN 1581708508 AND 1581708807

它扫描所有分区,而它们之间的数字15817085081581708807数字都在同一个分区中,我怎样才能让它只扫描那个分区?

标签: sqlhashmariadbpartitioning

解决方案


PARTITION BY HASH您已经发现了无用的原因之一。

在您的情况下,优化器会看到范围 ( BETWEEN) 并说“平底船,我将扫描所有分区”。

也就是说,当WHERE子句涉及范围并且您使用PARTITION BY HASH. PARTITION BY RANGE,另一方面,也许可以修剪。但是……有什么好处?它不会使查询更快。

我发现只有四种分区用途:http: //mysql.rjweb.org/doc.php/partitionmaint。听起来您的应用程序不适合任何这些情况。

该特定查询最好在不分区的情况下完成。而是有一个具有此“复合”索引的非分区表:

INDEX(timestamp, id)

它必须扫描所有行以发现MAX(id),但是有了这个索引,它是

  • 仅扫描 2 列索引
  • 不触及时间戳范围之外的任何行。

因此它将尽可能快。即使PARTITION BY HASH足够聪明地进行所需的修剪,它也不会运行得更快。

特别是,当您请求分区键的范围时,例如 with WHERE timestamp BETWEEN 1581708508 AND 1581708807,执行会在所有分区中查找所需的行。这是 Hash 的主要失败之一。即使它可以意识到只需要分区,它也不会比简单地使用我建议的索引更快。


推荐阅读