在按主键

时间:2017-08-27 10:18:09

标签: mysql performance

我正在研究大数据集。 并且想知道表格可以处理多少或多少最大记录,如果我按primary key搜索,我将得到0 second的结果。

使用最新的mysql。 所有查询都是read queries,因此我使用myisam。 目前的记录数为903,520,165 我的表结构是这样的

+-------------+----------+------+-----+---------+-------+
| Field       | Type     | Null | Key | Default | Extra |
+-------------+----------+------+-----+---------+-------+
| lock        | char(45) | NO   |     |         |       |
| key         | char(28) | NO   | PRI |         |       |
+-------------+----------+------+-----+---------+-------+

每秒会有10-500个选择查询。

唯一的要求是结果应该在0.00 seconds内返回。

那么哪些因素会影响查询返回result所花费的时间?

我正在使用最新的centos x6464 GB RAMSSD

所有查询都像

select lock from table where key = 'nnnnnnnnnnnnnnnnnnnnnnnnnnn';

我应该继续添加记录并继续测试结果是否在0.00 second中返回,如果查询时间增加,则停止添加新记录,这样的话? 或者还有其他因素?

或者有更好的mysql enginebetter db engine可用,就像

一样
key->value store

更新1:

我的意思是0 seconds我的意思是小于20 milliseconds或最大20-50 milliseconds

更新2:

我不确定,但我应该寻找

Fastest, non-memory-based, multi-process key-value store 

更新3:

只有读取,没有插入,没有更新,没有删除。 并且只选择限制为1个结果的查询按主键搜索。

更新4:

我创建了2个表,其中包含500k的小记录,1个是myisam,而另一个是innodb。

myisam (1 total, Query took 0.0000 seconds.)
innodb (1 total, Query took 0.0100 seconds.) 

我正在Widnows测试机上查看这个,在wamp上

更新5:

在Windows上从mysql控制台检查,myisam和innodb都在[1 row in set (0.00 sec)].

中输出了输出

但我需要以毫秒为单位的时间。

更新6:

alter tableinnodb开始已经过了36个小时。当前状态copy to tmp table

更新7:

我尝试使用SQL_NO_CACHE

进行查询

的myisam

1 row in set (0.00 sec)

innodb

1 row in set (0.00 sec)

更新8:

以毫秒为单位获取timinigs我尝试how to get load time in milliseconds or microseconds in mysql

last_query_execution_time()

输出

ERROR 1305 (42000): FUNCTION mydb.last_query_execution_time does not exist.

1 个答案:

答案 0 :(得分:2)

让我们将问题更改为"如何使用以下规格加快我的键值表?"。

您可以在旋转的硬盘驱动器上获得大约1个磁盘(而不是SSD)。

所以答案是

  • 如果未缓存索引块和数据块,则为0行(MyISAM需要2次磁盘命中) - 10ms(50行/秒)
  • 如果,但这两个块中的两个都没有缓存,则为1行 - 以10ms(100行/秒)为单位
  • 只要两个块都被缓存为所需的,然后是数百行。 (千/秒)

对于50ms,MyISAM在最坏的情况下只能提供2-3行。也许我们应该切换到"多少行/秒作为指标"?

下一步澄清。你在谈论很多连接,每个都要求一行吗?或者你在谈论一个要求连续(根据PRIMARY KEY)行的连接?

更快的速度:

  • 除非字符串实际上是固定长度,否则不要使用CHAR。使用VARCHAR。这会缩小索引和数据,从而使它们更易于缓存。

  • 从MyISAM更改为InnoDB。 InnoDB"集群" PK与数据。也就是说,当你找到PK时,数据就在那里。这消除了上面的第一种情况。现在是最坏的情况"在50ms内是5行。最好的情况是也许比MyISAM更好。 (那里有很多基准测试;可能没有一个完全匹配你的情况。)

需要另外澄清:您要更新行吗?删除行?添加新行?这些问题涉及到碎片化(MyISAM w / VARCHAR受到严格限制,InnoDB仅受到轻微影响)。

尺寸分析:

  • MyISAM w / CHAR:数据:75字节/行* 903M行+索引:~60 * 903M = ~120GB。完全缓存太多,甚至太多,无法将索引保留在RAM中(key_buffer_size)。

  • MyISAM w / VARCHAR:我不知道典型的大小,也不知道流失,我不愿意计算。但我怀疑64GB内存仍然太多了。

  • InnoDB w / VARCHAR:除PRIMARY KEY(key)之外不需要索引。足迹仍然可能是~120GB。因此,它再次无法完全缓存(innodb_buffer_pool_size)。

下一步澄清:如何'随机'使用key值?你会经常重复相同的吗?或者他们喜欢UUID / MD5(非常随机),你会在很多地方反弹。

如果非常随机,那么让我们分析一下缓存中某些东西的可能性。让我们说查找的索引是RAM缓存的两倍。这意味着只有一半的时间你会在缓存中找到该项目。现在我的回答是......

  • 有50%的缓存,你有一个磁盘命中另外50%,而InnoDB的50ms会给你一个每50ms 10行的平均。 (HDD上每秒200行(平均))。
  • 如果索引是缓存的20倍,则95%将是缓存未命中。那就是你会严重受I / O限制。 (InnoDB为105行/秒)

另一个澄清......密钥和/或锁可以以任何方式压缩吗?

  • 十六进制可以是UNHEXed的一半大小。
  • CHAR足够时,utf8默认为ascii吗? (CHAR的空间因子为3 !!我在上面的计算中没有考虑到这一点。)
  • 字符串是否会受益于COMPRESS()?在一些研究中,我已经看到"几乎任何超过10个字节的文本都可以从COMPRESS"中受益。英文文本或代码或XML通常缩小约3倍。你的45个字符可能缩小到20个。

如果您可以将表格大小减半,那么现在您有机会缓存​​所有内容。这将使你从200行/秒(InnoDB)到数千。