表字段重复与仅索引

时间:2019-07-15 18:50:34

标签: mysql optimization indexing query-optimization

我有一个巨大且非常繁忙的表(几千次插入/秒)。该表存储了登录日志,它具有bigint ID,该ID不是由MySQL生成的,而是由MySQL客户端上的伪随机生成器生成的。

简单地说,表中有loginlog_id, client_id, tons,of,other,columns,with,details,about,session....

此表上的索引很少,例如PRIMARY_KEY(loginlog_id)INDEX(client_id)

在我们系统的其他部分,我需要基于loginlog_id获取client_id。这种情况很少发生(仅几百SELECT client_id FROM loginlogs WHERE loginlog_id=XXXXXX /秒)。各种其他脚本会不时读取表登录日志,并且始终需要各种列。但是最常调用的方法是确定上面提到的通过loginlog_id获取client_id。

我的问题是:我应该在其中创建另一个表loginlogs_clientids并重复其中的loginlog_id,client_id(这意味着还要再插入几千个,对于每一个登录日志,我都会得到一个新的)。或者我应该对InnoDB通过PRIMARY KEY有效地处理我的查询感到满意。

我们有大量的RAM(128GB,其中大部分由MySQL使用)。 MySQL的负载在40%至350%CPU之间(我们有12个核心CPU)。当我尝试使用新表时,没有发现任何区别。但是我要求未来,如果我们的使用量增长更多,建议的方法是什么?重复还是索引?

谢谢!

1 个答案:

答案 0 :(得分:2)

否。

使用主键查找单行的表数据非常高效,并且两个表都花费相同的时间。

例外情况可能是行大小非常​​大(例如8KB +),而client_id例如一个在页面外存储的varchar,在这种情况下,您可能需要读取一个额外的数据块,至少从理论上讲,这可能会花费您几毫秒的时间。

即使该策略有优势,您实际上也不会通过创建新表来实现,而是在原始表中添加索引(loginlog_id, client_id)。 InnoDB将所有数据(包括实际数据)存储在索引结构中,因此添加索引与添加具有相同列的新表基本相同,但是不会出现同步这两个“表”的问题。 / p>

具有较小行尺寸的结构可以为远程扫描带来一些优势,例如MySQL将使用表的最小索引来评估select count(*) from tablename,因为它必须读取较少的字节。您已经有一个很小的索引(在client_id上),因此即使就此而言,添加这样的附加表/索引也不会起作用。如果您对主键进行了范围扫描(对于伪随机数据可能不太可能进行扫描),则可能需要考虑这一点,或者在有情况时记住这一点。

相关问题