MySQL。一个表包含1M条记录,或者10个表每个表包含100K条记录,这(性能)更好吗?

MySQL。一个表包含1M条记录,或者10个表每个表包含100K条记录,这(性能)更好吗?,mysql,database,performance,Mysql,Database,Performance,以前可能会问这个问题,但情况是这样的 我有一个大表(在使用InnoDB的MySQL上),它基本上是一个巨大的日志,没有任何关系方面的东西 3个字段:客户ID、时间戳、日志数据(这是一个tinytext,如“已访问首页”或“已登录”) 由于我将客户的活动记录在一个每天接收约10000名用户的网页中,因此该表增长非常快 在某一时刻,我想知道有多少客户在这个网站上做了任何事情 因此,我正在运行以下查询“从表中选择不同的客户ID;”,我开始注意到,随着表越来越大,查询所需的时间也越来越长,这是完全可以预

以前可能会问这个问题,但情况是这样的

我有一个大表(在使用InnoDB的MySQL上),它基本上是一个巨大的日志,没有任何关系方面的东西

3个字段:客户ID、时间戳、日志数据(这是一个tinytext,如“已访问首页”或“已登录”)

由于我将客户的活动记录在一个每天接收约10000名用户的网页中,因此该表增长非常快

在某一时刻,我想知道有多少客户在这个网站上做了任何事情

因此,我正在运行以下查询“从表中选择不同的客户ID;”,我开始注意到,随着表越来越大,查询所需的时间也越来越长,这是完全可以预料到的。在某个给定的时间,查询开始需要5分钟以上才能完成

我想找到一个更快的方法,所以我尝试了这个。假设我正在处理一个有一百万行的表。我首先将该表拆分为10个表,每个表有100K条记录。然后我运行“从表中选择不同的客户ID;”在每个表上,我只需在命令行上对所有结果进行“排序”(sort | uniq | wc),并得出相同的结果

令人惊讶的是,该方法的执行时间不到另一个方法的一半

我自己基本上已经回答了这个问题,10*100K表比1*1M表快,但可能我做错了什么,可能更像是性能调整的问题,因为表的设计应该确保无论大小都能很好地运行

让我知道你的想法

谢谢你的阅读

更新:以下是我创建表格的方式:

CREATE TABLE `mydb`.`mytable` (
 `Customer_ID` BIGINT( 20 ) UNSIGNED NOT NULL,
 `unix_time` INT( 10 ) UNSIGNED NOT NULL,
 `data` TINYTEXT NOT NULL,
KEY `fb_uid` ( `fb_uid` )
) ENGINE = INNODB DEFAULT CHARSET = utf8;

您似乎没有用户id字段上的索引,或者一个用户有很多行,比如说百万分之40000行。

虽然您的100K*10解决方案确实使查询速度更快,但听起来很难维护,可能不是最好的方法

“桌子的设计应确保无论大小都能发挥良好的性能”

您必须意识到,当表对于您正在使用的DB引擎来说太大时,这不可能是真的

那你能做什么呢?解决方案可能与您对该数据运行的查询类型有关

  • 上面的查询是否是唯一使用此数据的查询
  • 如果没有,在该表上运行的还有哪些查询

这里的一条经验法则是不要存储您不需要的数据。另一种方法是以易于查询的方式存储数据——即使您确实需要100万行原始数据,您仍然可以将一些聚合数据(或元数据)存储在另一个表中,例如每天唯一的客户id表,该表在一天结束时计算。

添加到其他表中,因为您说您没有做任何操作“幻想的关系材料”你可能还想考虑使用面向大规模数据集(简单表)的数据库解决方案。MongoDB就是一个例子。

我应该补充一点,这只有在数据库模式的其余部分也非常大且不相关的情况下才有意义:)

您需要一个以Customer\u ID开头的索引,以便查询速度更快。如果您的索引仅包含Customer\u ID,那么它将无法以最佳方式使用它。以下是创建它的方法:

CREATE INDEX idx_cid ON table (Customer_ID)
此外,您还可以通过以下方式直接从数据库中获取您的计数:

SELECT COUNT(DISTINCT(Customer_ID)) FROM table
如果你想把它缩小到一个时间范围,那么你需要一个综合指数:

CREATE INDEX idx_ts_cid ON table (TimeStamp, Customer_ID)
那么上个月的查询将是这样的:

SELECT COUNT(DISTINCT(Customer_ID)) FROM table
WHERE TimeStamp BETWEEN "2011-03-01" AND "2011-04-01"

您是否一个接一个地查询了10个表?如果您同时查询了所有表,这实际上是一个性能消耗,因为它占用了CPU/RAM1表5亿行—一个在0.02秒内覆盖1500万行的查询—因为它利用了精心设计的群集主键。您是否可以编辑问题并添加str表的结构(字段和索引的类型)?Customer_ID实际上是索引。我不知道是否有一个用户拥有大部分行,让我检查一下。我一定会尝试MongoDB。你有没有带性能数据的链接?我使用MySQL是因为它易于安装/配置。@almosnow这是MongoDB的基准页面: