MySQL索引基于INT列的最后一位

时间:2017-10-12 09:27:14

标签: mysql indexing mariadb partitioning

是否可以在MySQL中为int列的最后一位创建索引?

基于此answer我已根据int列的最后一位数创建了分区

CREATE TABLE partition_test(
  textfiled INT,
  cltext TEXT,
  reindexedAt TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  indexedAt TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  status TINYINT(2),
  postId INT)
PARTITION BY HASH(MOD(postId, 10))
PARTITIONS 10;

我正在尝试为postId的最后一位创建一个索引,以优化查询时间。有没有办法做到这一点或者postId上的简单索引就足够了?

尝试失败:

CREATE INDEX postLastDigit USING HASH ON partition_test (MOD(postId, 10));
(1064, u"You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'MOD(postId, 10))' at line 1")

CREATE INDEX postLastDigit ON partition_test (MOD(postId, 10));
(1064, u"You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'MOD(postId, 10))' at line 1")

更新 该表有超过100M的行。

我的目标是优化以下查询:

1)

SELECT cltext FROM partition_tables 
  WHERE postId in (<INT>, <INT>) 
  AND status IS NOT NULL

2)

SELECT cltext FROM partition_tables 
  WHERE postId in (<INT>, <INT>) 
  AND status IS NOT NULL
  AND reindexedAt BETWEEN (<DATE>, <DATE>)

MariaDB版本: 10.1.23-MariaDB-9 + deb9u1

3 个答案:

答案 0 :(得分:1)

您已使用mariadbmysql标记了自己的问题。如果您使用的是最新版本的MariaDB,则可以使用生成的列进行索引。如果您使用的是MySQL,如果您的MySQL版本至少为5.7,则可以这样做。

如果您使用的是较低版本的MySQL,则可以在表格中创建一个附加列,用于存储每行postId的最后一位数字,并使用该列进行索引/分区。

这意味着对应用程序代码的更改很少:在插入或更新之前,首先获取postId的最后一位数字,然后再插入/更新一个字段。作为替代方案,您最终可以使用触发器自动填充该附加列。

答案 1 :(得分:1)

您想要加快哪些查询?如果表上没有任何索引,任何查询都必须扫描整个表!如果你想要速度,首先要看索引。

如果您的查询为SELECT ... WHERE post_id = 123,则您的分区可能会使其运行速度提高10倍。但INDEX(post_id),无论是否进行分区,都会使其运行速度提高数百倍。

请提供SELECTs,以便我们为您提供帮助。

(好吧,如果你只是玩分区,其他人给你可行的答案。)

“分区修剪”很少比以修剪列开头的合适索引更快。

解决了声明的散列问题后,请报告查询是否比使用索引更快。即使对一个索引进行攻击,我预测分区也不会运行得更快,甚至可能运行得慢一些。

答案 2 :(得分:0)

使用虚拟列。在MariaDB 10.2中,您可以在virtual aka generated column上创建索引,就像这样

 CREATE TABLE t (
  num int,
  last_digit int(1) AS (num % 10) VIRTUAL,
  KEY index_last_digit (last_digit)
)

然后你可以在你的查询中使用last_digit,即SELECT ... WHERE last_digit = 1

在旧版本的MariaDB 5.2到10.1中,您需要指定 PERSISTENT 属性而不是VIRTUAL,因为无法对非持久生成的列进行索引。

相关问题