表大小对性能的影响有多大?

Dar*_*ius 6 mysql myisam performance optimization

假设我有一个包含 2938347 行的 MyISAM 表(以及其他表)。此表仅用于日志记录,不会经常清空。

如果不定期归档或删除这些行,是否保留该表会影响服务器性能?

那么,MySQL 服务器上的表/数据库大小如何,但不经常访问。这些表与经常访问/查询的表共存,我想知道它们是否导致问题。

大流士

Rol*_*DBA 3

这将取决于您发出的查询(假设大表是mydb.logtable)。

第 1 方面

首先,请考虑 MyISAM 存储引擎。它仅在 MyISAM 键缓存中缓存索引页(大小由key_buffer_size决定)。如果任何查询mydb.logtable从 读取大量索引页/var/lib/mysql/mydb/logtable.MYI,则查询 mya 会从其他表中清除索引页。这将导致对其他表的其他查询必须再次从磁盘重新读取它们的索引页。

第 2 方面

针对不经常访问的大型 MyISAM 表的任何查询都可能具有旧的索引统计信息,可能会导致将来进行全表扫描。在下班时间,您应该设置一个 crontab 作业来运行以下 SQL 命令:

ANALYZE TABLE mydb.logtable;
Run Code Online (Sandbox Code Playgroud)

这将重建索引统计信息。

第 3 方面

无论存储引擎(甚至 RDBMS)如何,任何请求超过表总大小 5% 的查询都会导致 MySQL 查询优化器停止使用索引并执行全表扫描。例如,如果查询一年的数据,而一张表包含的日志信息少于20年,则很有可能会发生全表扫描。

第 4 方面

如果索引的基数非常低,则某些键组合可能会导致查询不使用任何索引并执行全表扫描。

有关影响查询性能的低基数和 EXPLAIN plain 生成的演示,请参阅我的Nov 13, 2012帖子 索引必须覆盖所有选定的列才能用于 ORDER BY?

建议

您应该安排某种形式的日志轮换。也许是这样:

SET @tb1 = 'mydb.logtable';
SET @tb2 = CONCAT(@tb1,'_',date_format(now(),'%Y%m%d_%H%i%s'));
SELECT CONCAT('ALTER TABLE ',@tb1,' RENAME ',@tb2) INTO @sql_1;
SELECT CONCAT('CREATE TABLE ',@tb1,' LIKE ',@tb2) INTO @sql_2;
PREPARE s FROM @sql_1; EXECUTE s; DEALLOCATE PREPARE s;
PREPARE s FROM @sql_2; EXECUTE s; DEALLOCATE PREPARE s;
Run Code Online (Sandbox Code Playgroud)

这将使日志文件保持精简和平均,并归档最新的条目。