Mysql-估计删除索引的时间

Mysql-估计删除索引的时间,mysql,indexing,Mysql,Indexing,我们有一个相当未优化的表,定义如下: CREATE TABLE `Usage` ( `TxnDate` varchar(30) DEFAULT NULL, `TxnID` decimal(13,2) NOT NULL, `UserID2015` varchar(20) DEFAULT NULL, `UserRMN` decimal(13,0) DEFAULT NULL, `CustomerNo` decimal(13,0) DEFAULT NULL, `OperatorName` v

我们有一个相当未优化的表,定义如下:

CREATE TABLE `Usage` (
 `TxnDate` varchar(30) DEFAULT NULL,
 `TxnID` decimal(13,2) NOT NULL,
 `UserID2015` varchar(20) DEFAULT NULL,
 `UserRMN` decimal(13,0) DEFAULT NULL,
 `CustomerNo` decimal(13,0) DEFAULT NULL,
 `OperatorName` varchar(50) DEFAULT NULL,
 `AggregatorName` varchar(30) DEFAULT NULL,
 `TransAmount` decimal(10,2) DEFAULT NULL,
 `MMPLTxnID` decimal(13,0) DEFAULT NULL,
 `ProductType` varchar(30) DEFAULT NULL,
 `YearMonthRMN` varchar(50) DEFAULT NULL,
 PRIMARY KEY (`TxnID`),
 UNIQUE KEY `TxnID` (`TxnID`) USING BTREE,
 KEY `TxnDate` (`TxnDate`),
 KEY `OperatorName` (`OperatorName`),
 KEY `AggregatorName` (`AggregatorName`),
 KEY `MMPLTxnID` (`MMPLTxnID`),
 KEY `ProductType` (`ProductType`),
 KEY `UserRMN` (`UserRMN`),
 KEY `YearMonthRMN` (`YearMonthRMN`) USING BTREE,
 KEY `CustomerNo` (`CustomerNo`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=latin1
该表有170M的记录

我想删除主键,而是添加一个自动编号主键。到目前为止,指数下跌已经持续了2小时

为什么删除索引要花这么长时间,是否有排序发生

我如何估计删除索引的时间


当我添加自动编号时,我是否需要估计对表进行排序的时间,或者这对于新的自动编号索引来说是不必要的?

您不仅删除了索引,还删除了主键

通常,InnoDB表存储为基于主键的聚集索引,因此通过删除主键,它必须创建一个新表,该表使用辅助唯一键或自动生成的键作为聚集索引

我已经做了大量的MySQL咨询,而“这需要多少时间?”是一个常见的问题

在服务器上构建新的聚集索引所需的时间与构建新的聚集索引所需的时间相同。这很难预测。这取决于几个因素,比如服务器的CPU速度有多快,存储速度有多快,以及有多少其他负载同时进行,以争夺CPU和I/O带宽

换句话说,根据我的经验,不可能预测需要多长时间

您的表将使用
TxnID
作为新的聚集索引重建,该聚集索引恰好与主键相同。但很明显,MySQL服务器并不认为这种特殊情况可以使用进行就地更改的快捷方式

您的表还有八个其他二级索引,其中五个是varchar。它必须在表重构期间构建这些索引。除了聚集索引之外,构建这些索引还需要大量的I/O。这可能要花很多时间


添加新的自动递增主键时,将经历类似的过程。如果您在一条ALTER TABLE语句中删除了旧主键并创建了新的自动递增主键,则可以节省一些时间。

您不仅删除了索引,还删除了主键

通常,InnoDB表存储为基于主键的聚集索引,因此通过删除主键,它必须创建一个新表,该表使用辅助唯一键或自动生成的键作为聚集索引

我已经做了大量的MySQL咨询,而“这需要多少时间?”是一个常见的问题

在服务器上构建新的聚集索引所需的时间与构建新的聚集索引所需的时间相同。这很难预测。这取决于几个因素,比如服务器的CPU速度有多快,存储速度有多快,以及有多少其他负载同时进行,以争夺CPU和I/O带宽

换句话说,根据我的经验,不可能预测需要多长时间

您的表将使用
TxnID
作为新的聚集索引重建,该聚集索引恰好与主键相同。但很明显,MySQL服务器并不认为这种特殊情况可以使用进行就地更改的快捷方式

您的表还有八个其他二级索引,其中五个是varchar。它必须在表重构期间构建这些索引。除了聚集索引之外,构建这些索引还需要大量的I/O。这可能要花很多时间

添加新的自动递增主键时,将经历类似的过程。如果您在一条ALTER TABLE语句中删除了旧主键并创建了新的自动递增主键,则可以节省一些时间。

(我同意Bill的回答;这里有更多注释。)

我会终止这个过程,重新思考
自动增量是否有任何好处

我试着从问题之外去看“真正”的问题。在这种情况下,似乎还没有说出来,需要一个
自动增量
;请详细说明

您当前的
主键是6个字节。如果
INT
,您的新主键将为4个字节;如果
BIGINT
,您的新主键将为8个字节。因此,在磁盘空间利用率方面只有微不足道的节省或损失

通过
TxnID
进行的任何查找都会因为通过AI而减慢速度。由于
TxnID
唯一的
且非空的,因此它似乎是最佳的“自然”PK

PK是唯一的密钥,因此
Unique(TxnID)
是完全冗余的<代码>删除
这样可以节省空间而不会丢失任何东西。这是我的主要建议(只看模式)

当我看到一个表,其中基本上每个列都是
NULL
,我怀疑设计者没有意识到这些列是空的

DECIMAL(13,2)
将是很多美元或欧元,但作为PK,这是非常不寻常的。怎么了

拉丁语1
?没有全球化的计划

很多单列索引<代码>其中a=1和b=2要求复合
索引(a,b)

回到估算时间

如果
ALTER
重新构建了8-9个索引,那么is应该尽其所能使用磁盘排序。这涉及到将内容写入磁盘,使用一种高效的基于磁盘的排序(涉及一些RAM),然后读取排序结果以重新创建索引。排序是O(logn),因此它是非线性的。这使得很难预测所需的时间。一些新版本的MariaDB试图估计剩余的时间,但我不相信它

二级索引包括作为索引的列,以及PK的任何其他列。该表中的每个索引将占用大约5-10GB的磁盘空间。这可能有助于您转换为IOPs或其他格式。但请注意(假设您没有太多RAM),5-10GB将被重新读取几次
alter table `Usage` drop primary key, add id bigint auto_increment primary key