SELECT * FROM messages_messages WHERE (from_user_id=? AND to_user_id=?) OR (from_user_id=? AND to_user_id=?) ORDER BY created_at DESC
我有另一个查询,即:
SELECT COUNT(*) FROM messages_messages WHERE from_user_id=? AND to_user_id=? AND read_at IS NULL
我想索引这两个查询,但我不想创建2个单独的索引。
现在,我使用了2个索引:
[from_user_id, to_user_id, created_at]
[from_user_id, to_user_id, read_at]
我想知道我是否可以用一个索引而不是两个索引来做到这一点? 这是我对此表的唯一2个查询。
答案 0 :(得分:1)
The docs相当完整地解释了MySQL如何使用索引。特别是,它的优化器可以使用多列索引的任何左前缀。因此,您可以删除两个现有索引中的任何一个,而另一个则可以在两个查询中使用,尽管它对于一个查询比对另一个更有选择性/有用。
原则上,保留第一个索引可能更有利,前提是created_at
列按降序编制索引。在实践中,MySQL允许您指定索引列顺序,但实际上只实现升序。因此,在索引中使用created_at
可能并没有多大帮助。
答案 1 :(得分:0)
不,如果要完全优化,则需要这两个查询的两个索引。
一旦到达用于排序或范围比较的列(IS [NOT] NULL
计为此目的的范围谓词),您就不会从索引中添加更多列中获得任何好处。换句话说,您的索引可以包含:
因此,您无法创建一个为两个查询提供服务的四列索引。
正如@JohnBollinger所说,将这个减少到一个索引的唯一方法是创建一个优化一个查询的索引,并为第二个查询使用索引的子集。但那也行不通。