Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用1.5m记录优化mysql表,其中大多数记录被软删除_Mysql_Sql_Stored Procedures_Optimization_Myisam - Fatal编程技术网

使用1.5m记录优化mysql表,其中大多数记录被软删除

使用1.5m记录优化mysql表,其中大多数记录被软删除,mysql,sql,stored-procedures,optimization,myisam,Mysql,Sql,Stored Procedures,Optimization,Myisam,我有一个MySQL表,它有大约150万条记录,表大小为1.3GB 我在该表中使用了一种软删除机制,这意味着我有一个列deleted_,它指示行是否被删除以及何时被删除。如果未删除记录,则“已删除”的值为空 在这150万条记录中,只有3万条没有被软删除。这意味着它们经常被访问,而其他记录几乎不被访问,但在某些情况下,它们是被访问的 因此,该表被大量使用并查询未删除的记录,有时还查询软删除的记录 我有一个基数为35K的已删除记录的BTREE索引类型。随着时间的推移,表变得越来越重,显然它不是一个可扩

我有一个MySQL表,它有大约150万条记录,表大小为1.3GB

我在该表中使用了一种软删除机制,这意味着我有一个列deleted_,它指示行是否被删除以及何时被删除。如果未删除记录,则“已删除”的值为空

在这150万条记录中,只有3万条没有被软删除。这意味着它们经常被访问,而其他记录几乎不被访问,但在某些情况下,它们是被访问的

因此,该表被大量使用并查询未删除的记录,有时还查询软删除的记录

我有一个基数为35K的已删除记录的BTREE索引类型。随着时间的推移,表变得越来越重,显然它不是一个可扩展的解决方案

表引擎是MyISAM。其他大多数表都是InnoDB,但这个表使用存储过程进行大量查询,当我改为InnoDB时,查询速度要慢得多

我正在寻找一个解决方案,将不会涉及硬件的变化。当前的硬件足以使该表具有良好的性能,但一旦该表增长更多,情况就不会如此了

我想到的事情:

分区,但我不能使用分区,因为有些列是全文索引的。 将数据拆分为两个表。一个用于已删除的行,一个用于频繁访问和查询的未删除行。此更改需要大量的基础架构更改,因此我并不急于这样做。 创建一个新表,该表将在10/20分钟内与原始表同步一次,而不是拆分,并且只包含未删除的行。这将需要对基础设施进行小规模的更改,而且维护更加容易和安全。由于查询失败,拆分为两个表可能会导致丢失记录,因为删除操作实际上会将行从一个表移动到另一个表,因此需要复杂的机制 我还有其他选择吗?我可以优先考虑MySQL表中的某些行吗?记忆方面


我有10.3.20-MariaDB和32GB的RAM,MyISAM不缓存行,它只缓存索引。它依赖文件系统缓存来缓冲行

因此,您可以尝试确保至少索引已完全加载到缓存中:

增加键缓冲区大小,使其至少与此表的MyISAM索引一样大。使用“显示表格状态”查找索引大小。 如果有多个MyISAM表,可能需要专门为此表指定一个键缓存。看见 在启动时将索引预加载到密钥缓存中。看见

您可能还需要考虑适合于查询的多栏索引。比如,如果您有一个查询,其中user_id=1234,deleted_at为NULL,那么您应该在user_id,deleted_at上创建一个索引

需要哪些索引取决于要优化的查询


坦率地说,我会拆分表,以便删除的行位于第二个表中。这将使您的表大小减少98%,并使查询运行足够快,您不再需要使用MyISAM。

MyISAM不缓存行,它只缓存索引。它依赖文件系统缓存来缓冲行

因此,您可以尝试确保至少索引已完全加载到缓存中:

增加键缓冲区大小,使其至少与此表的MyISAM索引一样大。使用“显示表格状态”查找索引大小。 如果有多个MyISAM表,可能需要专门为此表指定一个键缓存。看见 在启动时将索引预加载到密钥缓存中。看见

您可能还需要考虑适合于查询的多栏索引。比如,如果您有一个查询,其中user_id=1234,deleted_at为NULL,那么您应该在user_id,deleted_at上创建一个索引

需要哪些索引取决于要优化的查询


坦率地说,我会拆分表,以便删除的行位于第二个表中。这将使您的表大小减少98%,并且可能使查询运行得足够快,您不再需要使用MyISAM。

即使是我也希望将数据拆分为两个表,以便将删除的记录与常用数据隔离开来。可能OP有一些限制。他们只是说它需要大量的基础设施更改,我想这意味着引用该表的其他代码必须更改。谢谢你的回答。我正在考虑第三种选择:创建一个新表,它将在10/20分钟内与原始表同步一次,而不是拆分。这将需要对基础设施进行小规模的更改,而且维护更加容易和安全。由于查询失败,拆分为两个表可能会导致丢失记录,因为删除操作实际上会将行从一个表移动到另一个表,因此需要复杂的机制,您对此有何想法?我会使用pt archiver,它是一种免费工具,可将数据从一个表安全地复制或移动到另一个表
另外它是Percona工具包的一部分。找出索引的大小你是说列索引的长度正确吗?即使是我也希望将数据拆分为两个表,以便将删除的记录与常用数据隔离开来。可能OP有一些限制。他们只是说它需要大量的基础设施更改,我想这意味着引用该表的其他代码必须更改。谢谢你的回答。我正在考虑第三种选择:创建一个新表,它将在10/20分钟内与原始表同步一次,而不是拆分。这将需要对基础设施进行小规模的更改,而且维护更加容易和安全。由于查询失败,拆分为两个表可能会导致丢失记录,因为删除操作实际上会将行从一个表移动到另一个表,因此需要复杂的机制,您对此有何想法?我会使用pt archiver,这是一种免费工具,可安全地将数据从一个表复制或移动到另一个表。它是Percona工具包的一部分。找出索引大小,您是说列索引长度正确吗?是否有某些查询显示性能非常差,您可以提供更好的优化?此外,表上的索引也可以提高性能。可以提供关于改进选项的请求,但是如果底层结构和特定索引以及查询的结构可以通过其他方式改进,那么您有多少RAM?什么版本的MySQL?@RickJames我有10.3.20-MariaDB,在10.3中InnoDB有32GB的RAMFULLTEXT。实际上,由于10.0.5,您的表足够小,因此应该可以轻松地缓存在RAM中。因此,获取然后丢弃98%的所需行的总体效率不太高。@RickJames您的意思是什么?我已经尝试将InnoDB与全文结合使用。但我发现这个查询并不是简单地涉及到距离计算,它在InnoDB中的性能很差。您是说在拆分表之后,转移到InnoDB是有意义的吗?是否有某些查询显示出明显的性能差,您可以提供更好的优化?此外,表上的索引也可以提高性能。可以提供关于改进选项的请求,但是如果底层结构和特定索引以及查询的结构可以通过其他方式改进,那么您有多少RAM?什么版本的MySQL?@RickJames我有10.3.20-MariaDB,在10.3中InnoDB有32GB的RAMFULLTEXT。实际上,由于10.0.5,您的表足够小,因此应该可以轻松地缓存在RAM中。因此,获取然后丢弃98%的所需行的总体效率不太高。@RickJames您的意思是什么?我已经尝试将InnoDB与全文结合使用。但我发现这个查询并不是简单地涉及到距离计算,它在InnoDB中的性能很差。你是说在拆分表之后,迁移到InnoDB是有意义的吗?