My object model is given below and would like your inputs on the number of indexes to create for faster query responses (on h2, mysql). Assumptions and questions are given below the following model.
@Entity
@Table(name = "user")
public class User {
@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "id", unique = true, nullable = false, insertable = false, updatable = false)
private Integer id;
@ManyToOne(fetch = FetchType.LAZY)
@ForeignKey(name = "fk_user_org_id")
@Index(name = "idx_user_org_id")
@JoinColumn(name = "org_id", nullable = false, referencedColumnName = "id")
@NotNull
private Organization organization;
@ManyToOne(fetch = FetchType.LAZY)
@ForeignKey(name = "fk_user_year_id")
@Index(name = "idx_user_year_id")
@JoinColumn(name = "year", nullable = false, referencedColumnName = "id")
@NotNull
private Year year;
@ManyToOne(fetch = FetchType.LAZY)
@ForeignKey(name = "fk_user_created_by")
@Index(name = "idx_user_created_by")
@JoinColumn(name = "created_by", nullable = false, referencedColumnName = "id")
@NotNull
private User createdBy;
@Column(name = "name", nullable = false)
private String name;
@Column(name = "desc")
private String desc;
@Column(name = "is_system", length = LEN_1)
@Type(type = "org.hibernate.type.YesNoType")
private boolean isSystem = false;
@Column(name = "user_type", nullable = false)
private UserType userType;
@Column(name = "status", nullable = false)
@NotNull
private Status status;
}
Our plan is to use multi column indexes instead of a single column index (i.e. create index user_idx based on (organization, year, isSystem, status, userType, createdBy)). Assuming I have this index, will I get optimized responses for my queries listed below.
- select * from user where organization=1 and year=2010;
- select * from user where organization=1 and year=2010 and isSytem=true or false; (i.e. system users or application defined users)
- select * from user where organization=1 and year=2010 and isSytem=false and userType=Manager (i.e. all managers)
- select * from user where organization=1 and year=2010 and isSytem=false and userType=Employee (i.e. all employees)
- select * from user where organization=1 and year=2010 and isSytem=false and userType=Manager and status=ACTIVE (i.e. Active users)
-
select * from user where organization=1 and year=2010 and createdBy=’Sam’ or ‘Joe’
Does [6] need a different multi column index, consisting of the above 3 columns? -
Since we are creating a multi column index as per my original assumption, can I safely remove the individual indexes (idx_user_org_id, idx_user_year_id, idx_user_created_by) as currently defined in the model?
You should switch the order of the columns in your index:
This allows it to better serve these two queries:
It doesn’t need a new index – it can use the existing one but in a less efficient way – only the first two columns will be used. Adding a new index for this query looks like a good idea though.
Yes. You should remove unused indexes otherwise they will just take up disk space and slow down table modifications without providing any benefit.