我必须在一个包含大约2000万行的非常大的表上运行2个简单查询。
表格列为id|user_id|earned_amount|created_at
查询1:
select user_id, sum(earned_amount) as total_earning
from earning_history
where user_id=XX;
查询2:
SELECT date(created_at) date, sum(earned_amount) as earning, count(id) as total_entry
FROM `earning_history`
where user_id=xx
GROUP by date
我必须运行第二个查询而不是第一个查询。所以我想考虑索引user_id
和created_at
列;
如果没有索引,执行第二次查询大约需要6-7秒。 我的问题是,
我应该只索引user_id列吗?或者我应该为user_id
和created_at
列编制索引吗?
我应该使用多个列索引,例如=> ALTER TABLE earning_history ADD INDEX (user_id, created_at);
?
答案 0 :(得分:0)
您可以使用复合索引来快速访问和减少数据检索值的访问。您可以使用where(user_id)列和select ..
中使用的列但是对于函数或计算列中的列使用,通常使用索引
anyqwey你应该在
上使用和索引一些好处create index my_index on my_table ( user_id, id, created_at, earned_amount)
或
create index my_index on my_table ( user_id, created_at,id, earned_amount)
答案 1 :(得分:0)
除非id
可以NULL
,否则请说COUNT(*)
而不是id
。然后,两个查询的最佳索引是此顺序:
INDEX(user_id, earned_amount, created_at)
这两个查询都会将其用作"涵盖的"指数。两者都需要user_id
成为第一个 - 以满足WHERE
。第一个查询将仅使用前两列,由于未使用的第3列,只有很小的开销。第二个查询不关心第二列和第三列所在的顺序,我选择此顺序使单个INDEX
适用于两者。
两个单独的单列索引 效率不高。 MySQL可能只使用一个索引,它将是(user_id)
。然后它必须在包含索引的BTree和包含所有列的BTree之间反弹 - 以便至少获得earned_amount
。 "覆盖"避免这种反弹。