Is an index on a SET column useful?

时间:2017-04-10 00:48:49

标签: mysql database postgresql database-design

The following question is framed with a particular lean towards MySQL and PostgreSQL, but I'd also be interested in answers regarding other database systems.

I'm designing a database and the SET column type appears to fit the bill in a few cases. One such example could be expressed as a boolean column for each day of the week, and I'm thinking of instead using MySQL's SET, SET('Sun','Mon','Tue','Wed','Thu','Fri','Sat').

Is an index on such a SET column useful? Would it speed up searches for rows matching individual days of the week? Particular combinations of days of the week? Or would it only speed up searches for full exact binary values of the field (such as 0101010 for Mon/Wed/Fri)?

2 个答案:

答案 0 :(得分:2)

Using PostgreSQL

Logically, if you wanted to only test for = the binary solution is the fastest. But, that's not to useful.

If not, you're probably better storing them as

  1. an array of enum,
  2. just simply as individual boolean fields. You can even use a bloom index.

In PostgreSQL you can create an enum type and then have an array of enum types. An index will speed this up.

CREATE TYPE dow AS ENUM ('M', 'Tu', 'W', 'Th', 'F', 'Sa', 'Su' );
CREATE TABLE foo ( days dow[] );

This would permit you to find all available Mondays with

SELECT * FROM foo WHERE days @> ARRAY['M']::dow[];

Or, all Monday, Wednesday, and Friday

SELECT * FROM foo WHERE days @> ARRAY['M','W','F']::dow[];

Or you could make them bools, index them, and then do

SELECT * FROM foo WHERE has_monday AND has_wednesday AND has_friday; 

答案 1 :(得分:0)

MySQL A SET实现为INT UNSIGNED,长度最多为8个字节(64个项目)。关于reference manual的评论有很多例子。其中包括如何将SET视为由其组成的位的示例。

正如您无法索引数字的“部分”一样,您无法真正索引SET的部分内容。

SET('Sun','Mon','Tue','Wed','Thu','Fri','Sat')对于7位数字而言是方便的。并且使用'Mon,Wed,Fri'来设置3个位也是一种非常方便的方式。关闭一点是非常麻烦的,除非你考虑位和INT以及2的幂。

如果你还不知道二进制数是如何由位组成的,那么你可能会发现SETs非常难以使用。

有一种情况,INDEX 可能值得拥有 - “覆盖”。也就是说,包含所有 SELECT中提到的列的索引将可能更快地运行SELECT。例如:

SELECT item FROM tbl WHERE FIND_IN_SET('Mon', my_set);
-- together with
INDEX(my_set, item)

该索引可能会加快查找包含星期一的项目。扫描“覆盖”索引可能比扫描表格更快。