2017-10-12 73 views
0

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

基于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; 

我试图创建的帖子ID为优化查询时间的最后一个数字的指数的最后一位在此基础上answer我已经创建的分区。有没有办法做到这一点或在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") 

UPDATE: 表有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的版本:23年1月10日 - MariaDB的-9 + deb9u1

+0

这是一个坏主意。此外,基本上*随机*分区不会改善任何事情。它肯定会损害性能,因为服务器将被迫搜索所有分区。 –

回答

1

您已经标记为mariadbmysql。如果您使用的是最近版本的MariaDB,则可以使用生成的列进行索引编制。如果你使用的是MySQL,如果你的MySQL版本至少为5.7,你也可以这样做。

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

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

+0

从一开始我试图避免这种选择。我会等待其他可能的答案,否则我会接受你的。 tnx Binarus –

+1

谢谢!我过去也是这样做的...... – Binarus

+2

@SimakisPanagiotis:你可以创建一个生成的列([Generated(Virtual and Persistent)Columns](https://mariadb.com/kb/en/library/generated-columns /))并索引它。 – wchiquito

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,因为非持久生成的列无法编制索引。

1

你想加快什么查询?没有任何索引的表,任何查询将不得不扫描整个表!如果你想要速度,首先看看索引。

如果您的查询是SELECT ... WHERE post_id = 123,您的分区可能会使其运行速度提高约10倍。但是,带有或不带分区的INDEX(post_id)将使其运行速度提高数百倍。

请提供SELECTs,这样我们可以帮助您加快速度。

(OK,如果你只是用分区玩耍,别人给你的答案可行)。

“分区修剪”很少比用修剪列开始一个合适的索引更快。

解决了哈希问题后,请报告查询是否比使用索引更快。即使与指数对比,我预测分区不会跑得更快,甚至可能会慢一点。

+0

像这样的随机分区可能会使查询运行速度慢10倍,而不是更快。 –