Nifle Asked: 2011-01-13 10:33:59 +0800 CST2011-01-13 10:33:59 +0800 CST 2011-01-13 10:33:59 +0800 CST MySQL中的“CREATE INDEX`是线性操作吗? 772 我的意思是: 如果在包含行的表上创建索引n需要t时间。在同一张表上创建索引1000*n大约需要一些1000*t时间。 我想要实现的是通过在更小的测试数据库上创建相同的索引来估计在生产数据库上创建索引所需的时间。 mysql index 4 个回答 Voted Best Answer David Spillett 2011-01-13T11:08:01+08:002011-01-13T11:08:01+08:00 索引创建本质上是一种排序操作,因此充其量最多具有顺序n log n平均增长的复杂性(您可能会发现它在某些情况下做得更好,并且不太可能做得更糟)。 如果您所有相关的数据页都适合 RAM 并且已经在 RAM 中,并且索引也适合,并且您的 DBMS 不会强制在创建完成之前写入索引页(因此索引块不会在磁盘上多次更新操作),那么将结果索引写入磁盘的速度将比执行排序所花费的时间更重要 - 因此您可能会发现行数与索引创建时间之间的线性关系更接近 -但如果你假设最坏的情况,你就不太可能感到不愉快! 请记住,除非您不打算在操作期间停止对生产数据库的访问,否则创建的任何索引都将与其他活动竞争 IO 带宽和/或锁定,因此如果您正在进行时序估计测试,您应该尝试考虑这一点在另一个系统上,即使它的配置相同。 jcolebrand 2011-01-13T15:12:33+08:002011-01-13T15:12:33+08:00 同样值得注意的是,如果您可以将用于索引的主轴与用于表的主轴分开,那么您将能够同时使用两个磁盘(仍然受限于中间磁盘控制器的速度,如果RAID 之类的,但它仍然比一个磁盘快)。 我意识到创建索引并不完全是同步读写操作,但它确实大大加快了速度。 警告:我自己是一个 MSSQL 的人,所以我不确定 MySQL,但我必须想象拆分轴的概念并不是 SQLServer 和 Oracle 所特有的(我也听说过它在那里谈论过,IIRC ). 我只是不知道如何着手建立这个概念。但在 SQLServer 术语中,这意味着除此之外还有一个单独的文件组PRIMARY,并将索引放在另一个文件组上,另一个文件组分配给一组不涉及的主轴PRIMARY(授予主轴放置与文件组完全是另一回事) RolandoMySQLDBA 2011-05-15T17:04:19+08:002011-05-15T17:04:19+08:00 如果大约 6 年前问这个问题,我会强调说不,因为它与 MySQL 4.x 有关。然而,MySQL 5.x 现在确实以线性方式执行索引创建。在我对上一个问题的回答中,我只是有一种怀旧的经历来解释这一点。 Rick James 2011-06-09T16:08:05+08:002011-06-09T16:08:05+08:00 这取决于。 变量 #1:如果 MySQL 选择即时构建索引,或者等到所有数据都进入,然后进行排序等,以构建索引。注意:必须即时构建 UNIQUE 索引(我认为)以便验证 UNIQUEness。InnoDB 的 PRIMARY KEY 与数据一起存储(或者您可以反之亦然),因此必须随机构建。 变量 #2:索引跟踪数据(例如 AUTO_INCREMENT 或时间戳)与随机数据(GUID、MD5)或介于两者之间的数据(部件号、名称、friend_id)。 变量 #3(如果索引是动态构建的):索引可能适合缓存(key_buffer 或 innodb_buffer_pool),也可能溢出到磁盘。 无论#1 的答案如何,跟踪数据的索引都是高效的,并且几乎是线性的。 随机 ID 很痛苦。如果索引不适合缓存,无论其他变量如何,构建它的时间都会比线性索引差得多。(在这种情况下,我不同意 Rolando。)一个带有 PK GUID 的巨大 InnoDB 表插入到 INSERT 时非常慢——计划普通磁盘每秒 100 行;如果你有 SSD,可能是 1000。LOAD DATA 和批量 INSERT 不会让您克服随机存储的缓慢问题。 3.53 到 5.6——变化不大。 多轴?几乎在任何情况下,RAID 条带化都比手动将其分配到这里和那里更好。手动拆分导致不平衡的情况——表扫描卡在数据盘上;仅索引操作卡在索引磁盘上;一个单独的查询首先命中索引磁盘,然后是数据磁盘(没有重叠);等等
索引创建本质上是一种排序操作,因此充其量最多具有顺序
n log n
平均增长的复杂性(您可能会发现它在某些情况下做得更好,并且不太可能做得更糟)。如果您所有相关的数据页都适合 RAM 并且已经在 RAM 中,并且索引也适合,并且您的 DBMS 不会强制在创建完成之前写入索引页(因此索引块不会在磁盘上多次更新操作),那么将结果索引写入磁盘的速度将比执行排序所花费的时间更重要 - 因此您可能会发现行数与索引创建时间之间的线性关系更接近 -但如果你假设最坏的情况,你就不太可能感到不愉快!
请记住,除非您不打算在操作期间停止对生产数据库的访问,否则创建的任何索引都将与其他活动竞争 IO 带宽和/或锁定,因此如果您正在进行时序估计测试,您应该尝试考虑这一点在另一个系统上,即使它的配置相同。
同样值得注意的是,如果您可以将用于索引的主轴与用于表的主轴分开,那么您将能够同时使用两个磁盘(仍然受限于中间磁盘控制器的速度,如果RAID 之类的,但它仍然比一个磁盘快)。
我意识到创建索引并不完全是同步读写操作,但它确实大大加快了速度。
警告:我自己是一个 MSSQL 的人,所以我不确定 MySQL,但我必须想象拆分轴的概念并不是 SQLServer 和 Oracle 所特有的(我也听说过它在那里谈论过,IIRC ). 我只是不知道如何着手建立这个概念。但在 SQLServer 术语中,这意味着除此之外还有一个单独的文件组
PRIMARY
,并将索引放在另一个文件组上,另一个文件组分配给一组不涉及的主轴PRIMARY
(授予主轴放置与文件组完全是另一回事)如果大约 6 年前问这个问题,我会强调说不,因为它与 MySQL 4.x 有关。然而,MySQL 5.x 现在确实以线性方式执行索引创建。在我对上一个问题的回答中,我只是有一种怀旧的经历来解释这一点。
这取决于。
变量 #1:如果 MySQL 选择即时构建索引,或者等到所有数据都进入,然后进行排序等,以构建索引。注意:必须即时构建 UNIQUE 索引(我认为)以便验证 UNIQUEness。InnoDB 的 PRIMARY KEY 与数据一起存储(或者您可以反之亦然),因此必须随机构建。
变量 #2:索引跟踪数据(例如 AUTO_INCREMENT 或时间戳)与随机数据(GUID、MD5)或介于两者之间的数据(部件号、名称、friend_id)。
变量 #3(如果索引是动态构建的):索引可能适合缓存(key_buffer 或 innodb_buffer_pool),也可能溢出到磁盘。
无论#1 的答案如何,跟踪数据的索引都是高效的,并且几乎是线性的。
随机 ID 很痛苦。如果索引不适合缓存,无论其他变量如何,构建它的时间都会比线性索引差得多。(在这种情况下,我不同意 Rolando。)一个带有 PK GUID 的巨大 InnoDB 表插入到 INSERT 时非常慢——计划普通磁盘每秒 100 行;如果你有 SSD,可能是 1000。LOAD DATA 和批量 INSERT 不会让您克服随机存储的缓慢问题。
3.53 到 5.6——变化不大。
多轴?几乎在任何情况下,RAID 条带化都比手动将其分配到这里和那里更好。手动拆分导致不平衡的情况——表扫描卡在数据盘上;仅索引操作卡在索引磁盘上;一个单独的查询首先命中索引磁盘,然后是数据磁盘(没有重叠);等等