【问题标题】:Impact on performance on an Indexed table after deletion Mysql [closed]删除Mysql后对索引表性能的影响[关闭]
【发布时间】:2021-04-08 18:13:12
【问题描述】:

我有一个包含 100 亿行的表,我的搜索查询提取了 150 万行已编入索引的行。我的问题是如果我删除不必要的行并减少到 3 百万行,我想我的搜索条件性能会提高。这是我的问题

  1. 如果我使用 100 亿行与 300 万行查询相同数量的数据,索引如何工作

这是我的表详细信息和简单的搜索查询。 @startdate 是一个输入,它总是一个月

CREATE TABLE `ABCD` (
  `ID` bigint(20) NOT NULL AUTO_INCREMENT,
  `VAL` varchar(255) DEFAULT NULL,
  `NVAL` varchar(255) DEFAULT NULL,
  `DOC` bigint(20) NOT NULL,
  `DESC` int(11) NOT NULL,
  `DateCreat` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`ID`),   
  KEY `IDX_DOC` (`DOC`), -- BTREE NON-UNIQUE
  KEY `INDEX_DESC` (`DESC`), -- BTREE NON-UNIQUE
  KEY `INDEX_DateCreat` (`DateCreat`) -- BTREE NON-UNIQUE
) ENGINE=InnoDB AUTO_INCREMENT=14755842749 DEFAULT CHARSET=utf8


SELECT  
     MONTH(@START_DATE) 'Month'
     ,count(distinct  DOC) 'Docs'

FROM 
    ABCD USE INDEX (IDX_DOC, INDEX_DateCreat)
WHERE
    DateCreat >= @START_DATE and DateCreat < @END_DATE

【问题讨论】:

  • 请,请read this。然后edit您的问题提供更多信息。
  • 我添加了额外的 cmets

标签: mysql indexing datatables query-optimization


【解决方案1】:

(评论太长了。)

这取决于。在某些情况下不会有任何改善;在某些情况下,会有显着的改进。

请提供SHOW CREATE TABLE 和样本DELETESELECT

“搜索”是如何完成的——通过PRIMARY KEY?二级钥匙?非索引列?

被删除的行是否在表的一个“末端”(例如清除“旧”数据)?还是散落的?

您如何处理返回的 150 万行? (太多了!)

索引是如何工作的。从阅读 Wikipedia 中的 B+Trees 开始。还是您使用FULLTEXT?还是SPATIAL

加速

你不想GROUP BY MONTH(DateCreat)SELECT MONTH(DateCreat) 吗?还是您真的要显示一系列月份,但只标记一个月?

无论如何,如果您有一个汇总表(可能按天计算),您可以有效地将汇总表中的计数相加,以非常快速地获取COUNT

重新索引

我仍然需要知道您是删除“旧”行还是分散在“月”中的行。

如果您要删除“旧”行,那么PARTITIONing 会提高效率。更多详情:http://mysql.rjweb.org/doc.php/partitionmaint

如果您要删除分散在整个表格中的行,让我们进入 BTrees。数据将由 PK 排序。那是id,它可能是按时间顺序排列的(或至少大致如此)。

数据存储在块中,每个块可能有 100 行,如果这些 varchar 保存“短”字符串,可能会更多。一个块是 16KB。

当您删除 分散 行时,您将缩小某些块中的行数,但不会减少块数。 (OK,如果相邻的两个block足够稀疏,就会合并在一起。)

查询一个巨大的表(太大而无法缓存在内存中)的速度主要取决于所触及的的数量。

所以,DELETE 对这个查询的性能没有多大帮助。

更好的索引

对于这个查询,将INDEX(doc) 替换为INDEX(doc, date_creat) INDEX(date_creat) 替换为INDEX(date_creat, doc) 将加快查询速度,甚至在任何删除之前。 (更改两个索引都可以。但这可能需要很长时间。)

每个二级索引都是一个 BTree。这个 BTree 在删除过程中会发生类似于我上面提到的变化。也就是说,删除一些文档很可能会从第一个索引中删除块,或者删除“旧”行很可能会删除第二个索引的一大块。同时,其他索引大多会变得不那么密集。

那些建议的索引是“覆盖”的。这意味着查询只能使用INDEX 来执行。

索引效率

我不得不再次说“这取决于”......

根据经验,如果要使用超过大约 20% 的索引,则该索引将被忽略。也就是说,如果WHERE DateCreat &gt;= @START_DATE and DateCreat &lt; @END_DATE 是一个 日期范围,则将考虑 DateCreat 开头的任何索引。对于较大的范围,将忽略索引并使用表。

最佳总结

更大的日期范围:INDEX(date_creat, doc) -- 过滤将发生覆盖。没有它,整个表都会被扫描;在这种情况下,表中的块数很关键——所以,回到 Delete 做了什么或没做什么。

较小的日期范围:INDEX(date_creat, doc) 最好,但 ``INDEX(date_creat)` 排在第二位。 Delete 影响较小,但现在需要在 BTree(数据和索引)中都考虑效果。

【讨论】:

  • 这没有提供问题的答案。要批评或要求作者澄清,请在他们的帖子下方留下评论。 - From Review
  • 这是一个大表,计划清除。我知道索引是如何工作的,但想知道索引搜索是如何工作的 w.r.t 行数。如果索引帮助我搜索条件并提取相同数量的数据,那么行数是否重要?
  • @Musthafa - 对不起,如果我让你不知所措。
  • @MarkBenningfield - OP 和我添加的内容是否足以证明重新打开的合理性?
  • @RickJames:我不这么认为,不。问题基本上是,“如果我这样做会发生什么?”。答案是“这样做并找出答案”。对于性能问题,答案始终是测试和分析,而不是猜测。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-02-03
  • 2012-09-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-08
  • 1970-01-01
相关资源
最近更新 更多