【问题标题】:Force hidden clustered index in innoDB在 innoDB 中强制隐藏聚集索引
【发布时间】:2016-11-23 09:59:09
【问题描述】:

我有一个表,其 ID 是“真正的主键”的哈希值。如果我错了,请纠正我,但我认为我在这个表中的插入非常慢,因为这个键上有聚集索引(插入 100 000 行需要几分钟)。 当我将 key 更改为非聚集索引时,我的印象是 innoDB 仍然秘密地聚集在它上面。

有没有一种简单的方法可以避免我的主键上的 mysql 集群,而无需定义自动增量主键?

【问题讨论】:

    标签: mysql sql innodb mariadb


    【解决方案1】:

    InnoDB 必须有一个PRIMARY KEY

    1. Innodb 的首选是明确的PRIMARY KEY,无论AUTO_INCREMENT 与否。
    2. 然后是UNIQUE 键,但前提是所有列都不是NULLable
    3. 最后,InnoDB 将创建一个隐藏的 6 字节整数,其行为有点像 auto_increment。

    场景 1. 插入表必须找到所需主键所在的块。对于AUTO_INCREMENT 和上面的#3,这将是表中的“最后一个”块。这 100K 行将进入表“末尾”的大约 1000 个块中。

    场景 2. 否则(非 AI,但显式 PK;或 UNIQUE),需要找到一个块(可能从磁盘读取),检查密钥是否为 dup,然后更新该块并标记以供以后重写到磁盘.

    如果所有块都适合缓冲池,那么其中任何一个的速度基本相同。但是如果表太大而不能被缓存,那么场景 2 会变得很慢——事实上随着表的增长越来越慢。这是因为 I/O。 GUID、UUID、MD5 和其他哈希因遭受这种减速而臭名昭著。

    另一个问题:事务完整性规定每个事务都会引发一些其他 I/O。你的 100K 插入 100K 事务吗? 1 笔交易?最好的办法是在每个事务中以 100 到 1000 行为一组进行批处理。

    我希望这些原则能让你弄清楚你的情况。如果没有,请为您正在考虑的每个选项提供CREATE TABLE。然后我们可以讨论您的详细信息。还要提供SHOW VARIABLES LIKE 'innodb_buffer_pool_size'; 和你有多少内存。

    【讨论】:

    • 接受您的回答,因为它帮助我理解问题不在于我的 SQL 表结构或 SQL,而在于我使用 SQL 库的方式(续集)。当密钥已经存在时,我更改了程序以请求宽恕,而不是首先检索实体。然后我可以使用批量插入方法,该方法在大约 1 秒内插入 100K 行,正如预期的那样。
    猜你喜欢
    • 2019-06-24
    • 2012-10-14
    • 2015-05-13
    • 1970-01-01
    • 2020-07-27
    • 2013-08-07
    • 1970-01-01
    • 2011-05-21
    相关资源
    最近更新 更多