根据此查询,应该对哪一列或哪些列进行索引以优化查询性能?
SELECT *
FROM `activities`
WHERE (user_id = 90000 AND activity_type_id IN(300,400,808,9494))
ORDER BY created_at DESC
LIMIT 70
答案 0 :(得分:2)
当然,WHERE子句中的所有列都应编入索引。
但IN子句可能需要进行表扫描。
我认为阅读这些答案可能有所帮助:
答案 1 :(得分:2)
通常,选择过滤器可以使用user_id
或activity_type_id
或两者的索引(按任意顺序)。
订购操作可能会在created_at
上使用过滤器。
对于此查询,(user_id, activity_type_id)
上的复合索引可能会给出最佳结果,假设MySQL实际上可以使用它。如果做不到这一点,将user_id
编入索引可能比activity_type_id
更好,因为它可能提供更好的选择性。想到这一点的一个原因是,如果索引使用activity_type_id
上的索引,则会有4个子部分进行扫描,而只扫描一个子部分,如果它仅使用user_id
上的索引。 / p>
尝试依赖排序顺序的索引可能意味着全表扫描,因此不太可能有益。我不会在created_at
上创建索引来支持此查询;可能还有其他问题,这将是有益的。
答案 2 :(得分:0)
您正在对user_id和activity_type_id进行查找,因此请在两列上创建索引。
答案 3 :(得分:0)
我只会将user_id
..
答案 4 :(得分:0)
假设您没有在实际生产代码中隐藏JOIN,则索引“activity_type_id”应该是最好的。
答案 5 :(得分:0)
我在活动表上添加两个索引,一个在(user_id,activity_type_id)上,另一个在(created_dt)上。我也很难看到'活动'表中的哪些字段实际使用了;如果您可以减少检索的字段数,则可以缩短响应时间。我还会在对数据库进行任何更改之前获取查询计划,然后将其与在进行任何/所有更改后生成的计划进行比较。
分享并享受。
答案 6 :(得分:0)
我根本不会创建任何其他索引,而是我会设计我的表,以便它充分利用innodb集群主键!
create table activities
(
user_id int unsigned not null,
activity_id smallint unsigned not null,
primary key (user_id, activity_id) -- composite clustered primary key order is important
)
engine=innodb;
或
create table activities
(
user_id int unsigned not null,
activity_id smallint unsigned not null,
primary key (activity_id, user_id) -- hmmmm the other way round, why is that ?
)
engine=innodb;
另外,请阅读以下内容:
MySQL and NoSQL: Help me to choose the right one
How to avoid "Using temporary" in many-to-many queries?
60 million entries, select entries from a certain month. How to optimize database?
Rewriting mysql select to reduce time and writing tmp to disk
希望它能帮助并记住innodb FTW;)
答案 7 :(得分:0)
要做出正确的决定,您必须考虑以下因素:
如果user_id是主键的一部分(你说它可能是),那么主键是表的聚簇索引吗?如果是,那么user_id是否位于聚集索引的第一个位置?如果是这样,那么您希望每个用户有多少活动?如果每个用户有1-40个活动,那么添加另一个索引将没有用,并且会损害插入性能。原因是用户的所有活动行将聚集在一起并且可能位于同一数据库页面上,因此将activity_type_id添加到索引将无济于事。
如果主键没有聚集且user_id不在主键的第一个位置,或者user_id不在主键中,那么最好的选择是使用user_id,activity_type_id的非聚集索引。查询优化器应该足够智能以使用索引,因为user_id和activity_type_id都在where语句中,即使存在IN子句也是如此。您还可以在索引末尾添加created_at,因为您以这种方式排序查询结果。
专门为一个查询创建索引,但如果查询被大量使用,通常是必要的。