仅在 mysql 中的某些行上创建索引

Posted

技术标签:

【中文标题】仅在 mysql 中的某些行上创建索引【英文标题】:Create an index only on certain rows in mysql 【发布时间】:2011-02-03 07:10:06 【问题描述】:

所以,我有一个有趣的要求,即只在特定行集的表上创建索引。

这是我的桌子的样子:

USER: userid,friendid, created, blah0, blah1, ..., blahN

现在,我想在以下位置创建索引:

(userid,friendid, created)

但仅限于 userid =friendid 的那些行。原因是该索引仅用于满足 WHERE 子句包含“userid =friendid”的查询。会有很多行不是这种情况,我真的不想浪费索引上的所有额外空间。

另一种选择是创建一个表(查询表),该表在插入/更新此表时填充并创建一个触发器来执行此操作,但我再次猜测该表上的索引意味着数据将是存储两次。

mysql如何存储主键?我的意思是该表是按主键排序的,还是按插入顺序排序的,PK 就像一个普通的唯一索引?

我检查了聚集索引 (http://dev.mysql.com/doc/refman/5.0/en/innodb-index-types.html),但似乎只有 InnoDB 支持它们。我正在使用 MyISAM(我之所以提到这一点,是因为我可以在查询表中的这 3 个字段上创建聚集索引)。

我基本上是在寻找这样的东西:

ALTER TABLE USERS ADD INDEX (userid,friendid, created) WHERE userid=friendid

【问题讨论】:

显然,我的要求毕竟不是那么好笑。 db.cs.berkeley.edu/papers/ERL-M89-17.pdf 【参考方案1】:

关于条件索引:

你不能这样做。 MySQL 没有这样的东西。

关于主键:

这取决于存储引擎。 MySQL 没有定义如何存储或检索数据,这取决于存储引擎。

MyISAM 不会对行的存储方式强制执行任何顺序;它们被附加到表的末尾,但删除的间隙可以重复使用,即使没有任何 DELETEs,UPDATE 查询也会使事情发生故障。

InnoDB 按主键顺序存储行。

【讨论】:

可以使用基于函数的索引,但 MySQL 肯定不支持。 谢谢!!您可能知道的任何 hack/近似值? @OMG ponies:你知道支持基于函数索引的数据库吗? @dhruvbird:甲骨文(据我所知为 9i+),SQL Server 2008+ has filtered indexes。我可以看到 DB2 支持它们,但我不知道。 @IMG 小马:谢谢!!似乎 PGSQL 也支持过滤索引:en.wikipedia.org/wiki/Partial_index【参考方案2】:

很难说出您在这里实际尝试做什么(为什么用户需要成为他自己的朋友?)但在我看来,简单地重新考虑您的数据库架构就可以解决这个问题。

表 1:用户:用户 ID,已创建,blah0,blah1,...,

表 2:userIsFriend (user1,user2,...)

只需对表 2 进行索引(其元素可能对表 1 具有外键约束)

顺便说一句,如果你想用 mySQL 做任何半严肃的事情,你可能应该使用 InnoDB,恕我直言。

【讨论】:

USERS 表只是一个例子。此外,在某些情况下,无论如何您都希望在数据库中为这样的表提供一个身份行(用户是他/她自己的朋友)。 就 InnoDB 而言,我没有使用事务,所以我不想为它们付出代价。

以上是关于仅在 mysql 中的某些行上创建索引的主要内容,如果未能解决你的问题,请参考以下文章

MySQL如何索引JSON字段

数据库 之 MySQL的索引

Oracle - 仅在不存在时创建索引

SQL Server里面啥样的视图才能创建索引

如何在 MySQL 中的 json 列上创建索引?

如何仅在某些行上显示图像按钮