MySQL中的“ CREATE INDEX”是线性运算吗?


20

我的意思是:

如果使用以下命令在表上创建索引 n行需要花费t时间。在同一张表上创建索引1000*n大约需要花费1000*t时间。

我要实现的目标是通过在小的测试数据库上创建相同的索引来估计在生产数据库上创建索引所需的时间。

Answers:


16

索引创建本质上是一种排序操作,因此充其量是要增加订单的复杂性n log n平均而言最高(您可能会发现它在某些情况下会更好,并且不太可能变差很多)。

如果所有相关数据页都适合RAM并且已经在RAM中,并且索引也适合,并且您的DBMS不会在创建完成之前强行写入索引页(因此,索引块不会在磁盘上多次更新)操作),那么将结果索引写入磁盘的速度将比执行排序所花费的时间更为重要-因此您可能会发现行数与创建索引所花费的时间之间的线性关系更加紧密-但是如果您假设情况更糟,那么您不太可能会感到意外!

请记住,除非您不希望在操作期间停止对生产数据库的访问,否则任何创建的索引都将争夺IO带宽和/或与其他活动的锁定,因此,如果要进行时序估计测试,则应尝试解决这一问题。在另一个系统上,即使其配置相同。


7

同样值得注意的是,如果您可以将索引的主轴与表的主轴分开,那么您将能够一次从两个磁盘工作(仍然限于中间磁盘控制器的速度,如果RAID或类似设备,但仍比一个磁盘快。

我意识到创建索引并非完全是同时读写操作,但是确实可以大大加快速度。

CAVEATS:我本人是MSSQL专家,所以我不太了解MySQL,但我可以想象到,分割主轴的概念并非特定于SQLServer和Oracle(在IIRC上我也曾听说过) )。我只是不知道该如何建立这个概念。但是用SQLServer的术语来说,这意味着除了要有一个单独的文件组,而且还要PRIMARY在另一个文件组上放置索引,而将另一个文件组分配给一组主轴却不涉及PRIMARY(授予主轴放置与文件组的关系完全是另一回事)。


1
在Oracle中几乎是同一件事–只有文件组被称为表空间


1

这取决于。

变量1:如果MySQL选择动态建立索引,或者等到所有数据都输入后,再进行排序等操作来建立索引。注意:(我认为)必须唯一地建立UNIQUE索引,以便可以验证UNIQUEness。InnoDB的PRIMARY KEY与数据一起存储(或者您可以声明相反),因此必须随机构建。

变量#2:索引跟踪数据(例如AUTO_INCREMENT或时间戳)与随机数据(GUID,MD5)还是介于两者之间(零件号,名称,friend_id)。

变量3(如果索引是动态生成的):索引可能适合缓存(key_buffer或innodb_buffer_pool),或者它可能溢出到磁盘。

不管答案是#1,跟踪数据的索引都是有效的,并且几乎是线性的。

随机编号很痛苦。如果索引不适合缓存,则无论其他变量如何,建立索引的时间都将比线性时间差得多。(在这种情况下,我不同意Rolando。)巨大的带有用于PK的GUID的InnoDB表插入到INSERT计划中的速度非常慢,对于普通磁盘来说,计划为100行/秒。如果您有SSD,则可能为1000。LOAD DATA和批处理INSERT不会使您摆脱随机存储的缓慢性。

3.53至5.6-变化不大。

多主轴?在几乎所有情况下,RAID条带化都比手动将其分配给此处和此处更好。手动拆分会导致不平衡情况-表扫描卡在数据磁盘上;仅索引操作卡在索引磁盘上;单个查询首先命中索引磁盘,然后命中数据磁盘(无重叠);等等

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.