MySQL高性能,适用于许多SELECT / INSERT / UPDATE / DELETE


9

我正在创建一个模块,其中每个用户经常在10到300秒内将记录插入表中。

时间到时,记录将被删除。情况是:会有很多用户,记录会经常更改-这将如何影响此表的应用程序性能,因为记录会经常更改,我想知道mysql是否适合呢?就像索引会来来去去一样,此特定表的数据更改速度约为200次/秒。也许我正在为这种工作选择一个不好的解决方案。有什么建议么 ?

谢谢!


2
您是否尝试过将数据存储在内存缓存中,然后每隔几秒钟刷新一次事务?

3
“该特定表的数据变化为200次/秒,”我认为该行说明了该数据应保存在内存中,它必须保留的生命周期很小,因此可能不应该将其存入磁盘吗?

索引来去去去?我想不出为什么您需要经常创建和删除索引的任何原因。
巴里·布朗

Answers:


3

必须考虑的一件事是MySQL如何将缓冲区用于其主要存储引擎:InnoDBMyISAM

这些存储引擎之间在内存中缓存的内容差异很大。

InnoDB缓存数据页面和索引页面。它们被加载到InnoDB缓冲池中,该缓冲池的大小由innodb_buffer_pool_size决定

MyISAM仅缓存索引页,并且将它们加载到键缓存(键缓冲区)中,键缓存的大小由key_buffer_size决定

您必须使用information_schema.tables来获取磁盘上占用的数据和索引大小,以便正确调整InnoDB缓冲池和MyISAM密钥缓存的大小

根据您拥有的数据量和允许的时间量,可以按以下方式预热缓存:

对于每个表TableT

  • 转到每个索引NDX
  • 对于每个索引NDX
    • 运行SELECT 在NDX每一列,至少有一列没有索引TableT上从TableT上

这样可以保证每个数据和索引页至少被读取一次。他们将坐在缓存中。Percona部分和原则上实践了这一概念。Percona将这一概念构建到mk-slave-prefetch中。该程序的作用是

  • 在从站处理其中的SQL之前,读取中继日志在从站上
  • 从中继日志中获取一条SQL语句,并使用WHERE,GROUP BY和ORDER BY子句作为选择索引的指南,将其转换为SELECT
  • 执行来自转换后的SQL的SELECT语句

这迫使从服务器拥有从服务器快速处理SQL所需的99.99%的数据。如果您手动将故障转移到从属服务器,并将其升级为主服务器,这也使从属服务器做好了准备,就像您从其失败的主机开始一样。

结论

在拥有大量INSERTS,UPDATE和DELETE的环境中,让缓存准备就绪,愿意并且能够让您使用的优势无与伦比。

试试看 !!!

警告

随着诸如memcached之类产品的诞生,一些产品不再需要执行适当的MySQL调整。诚然,许多站点都受益于通过控制数据的缓存行为而提供的数据检索功能的增强,正如开发人员使用memcached所迅速看到的那样。通过切换存储引擎或正确配置MySQL,许多其他站点已经实现了相同的性能优势。在放弃数据库并将其严格用作存储库之前,请充分利用数据库。继续进行尽职调查,您可能会惊喜地发现MySQL将为您做什么。


5

如果那是一个不好的解决方案,则取决于很多事情。此数据是否需要持久化?否则,仅将这些数据保留在内存中的解决方案可能会更好。

“很多用户”并没有真正帮助任何人。如果“很多”意味着几百个MySQL,MySQL很可能会很好。(尽管取决于数据库还必须处理什么。几千种也应该可以工作。)

毕竟,没关系,只要您写这些记录来保留还是在几秒钟到几分钟后将其删除。删除仅使两项操作合而为一。MySQL肯定可以处理大量的创建和删除记录。确保使用简单的索引再次找到这些记录以进行删除。

但是,如果没有实际数字以及有关数据库服务器使用的硬件的某些信息,就无法非常精确地回答。

最好的办法是编写一些小型应用程序,该应用程序可以简单地模拟您认为无需进行大量实际处理即可获得的负载量,只需将大量记录放到服务器上,然后删除它们,以相同的速度运行一些查询,例如程序的其余部分将生成。查看您的服务器,看看是否有任何影响。

不确定,但是可以为MySQL设置选项以使其完全将表缓存在内存中。在许多情况下,无论如何它都会这样做,并且很可能您无需进行太多更改。但是,如果您谈论的是非常大量的用户和记录,则可以调整一些参数来优化缓存以满足您的特殊需求。


4
+1用于建议一种将数据保留在内存中的解决方案。

3

这是个疯狂的主意。它涉及假设而非总是推荐的做法(例如更新密钥)-我会对此提出很多反对意见,但是在这里...

假设您有大量的行和大量的删除操作,则可以通过在表上创建2个分区来提高删除性能。分区的不同之处在于密钥的第一位。例:

键值1123234441用于活动行,键值:9123234441用于非活动行(本示例中的第一位数字使用如下:1 =活动,9 =非活动)。

现在,当用户删除一行时,您实际上并没有删除该行,而是更新了密钥(糟糕!),这将自动将行移至非活动行分区。

当然,您需要限制选择以仅从活动分区读取数据。现在最酷的部分是删除非活动行分区非常快。

就像我之前说的,如果只有1个表,这将起作用。我还没有测试过,所以这只是一种理论方法,但是我体验了分区删除的速度,而且速度惊人。

为了增强您的选择,请使用适当的索引并增强插入,以最小化行大小和索引数(此语句非常通用...)

有关参考,请参见:http : //dev.mysql.com/doc/refman/5.1/en/partitioning-types.html 希望这会有所帮助。


2
我不确定这是否对这个特定问题有意义(我的猜测仍然是,mysql将缓存整个事件,并且最有可能这些记录看不到磁盘)。但是+1指出了我目前不知道的有趣的优化技术。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.