sql - Mariadb 扫描时间戳列中的所有分区
问题描述
我有一个表分区:
HASH(timestamp DIV 43200 )
当我执行此查询时
SELECT max(id)
FROM messages
WHERE timestamp BETWEEN 1581708508 AND 1581708807
它扫描所有分区,而它们之间的数字1581708508
和1581708807
数字都在同一个分区中,我怎样才能让它只扫描那个分区?
解决方案
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 的主要失败之一。即使它可以意识到只需要分区,它也不会比简单地使用我建议的索引更快。
推荐阅读
- vue.js - 如何在旁边添加div
- 在 bootstrap-vue 下拉切换中?
- python - 使用python进行线性规划
- python-3.x - 删除具有标题但所有行均为空的列 Python 3 和 Pandas
- c# - 为什么我没有从我的网络请求中得到任何东西?我应该寻找什么?
- c++ - 如何在 Gtkmm4 中获取 Gtk::Window 的 XId
- sql - 如何使用 oracle 查询找出以下输出
- javascript - 如何在 Map 中找到键,其中键包含某个值?
- java - 使用 Comsol API 在 Java 中出现 FlException:无法获取用户名和密码
- r - 是否可以使用 spData/tmap 包创建英国县的地图
- node.js - Google Translate API:音译输入