在sql中插入,删除和更新期间会发生什么?

时间:2017-02-21 12:34:11

标签: mysql indexing innodb b-tree

我想了解一些关于mysql架构的事情。 1. sql进程如何在索引表中插入,删除,更新操作? 2.据说当索引页不在缓冲池中时,只在更改缓冲区中进行更改。因此,如果在缓冲池加载相关索引页面之后进行了更改,那么它也必须更改磁盘中的同一页面。对?那么必须在三个不同的地方进行操作? 3.如何将NULL值编入索引?它们将存储在b +树中的哪个位置? 4.如果我们更新作为聚集索引的数据,那么何时在磁盘中更新? 5.批量装载时会发生什么?

1 个答案:

答案 0 :(得分:2)

如何处理插入/更新/删除...

  1. 获取(和缓存)定位要更新/删除的行所需的索引块,或者将插入新行的块。
  2. 获取数据块。请注意,所有索引都包含PRIMARY KEY,它与数据集群在一起。
  3. 修改数据块以反映更改。还要处理记住旧数据 - 如果是最终ROLLBACK
  4. 更新唯一索引块(包括PK)。
  5. 在更改缓冲区中存储非唯一索引更改。 (如你所说。)
  6. 更改缓冲区设计为对实际索引块“透明”。

    • 通过索引查找将始终“做正确的事”,无论条目是否在CB中。
    • 将CB条目折回到实际索引块中是在“后台”和/或用完房间时完成的。 (我认为CB默认为buffer_pool的1/4。)
    • 在事务日志中存储了足够的信息,因此崩溃不会丢失挂起的索引更新。
    • 显然,CB是为了表现而发明的。索引更新可以延迟,同时比需要更新的索引块(16KB)占用更少的空间(通常只有几十个字节)。多个更改(通常)可以应用于单个索引块 - 这是主要的节省。但请注意,由于随机性,UUID,MD5等无法很好地利用CB。当前日期时间/时间戳的非唯一索引是CB的缓冲真正发光的情况。

    (对不起,我对CB的了解对你所要求的水平有点模糊。我建议你阅读代码。)

    NULL ...我相信它被视为一个单独的值,它在B + Tree中的所有非空值之前进行排序。但是为了混淆这个问题,有一个标志确定空值是否被视为彼此相等。 PRIMARY / UNIQUE键有限制。

    与NULL相关...在对PARTITION BY RANGEDATE的某些变体/函数执行DATETIME时,无效日期变为NULL,该日期明确存储在UNIQUE中'第一'分区。新手常常对为什么分区修剪似乎不起作用感到困惑。 (推荐的部分解决方法:使用'first'分区,否则为空。)

    群集 PRIMARY KEY索引...所有(?)写入操作必须检查所有唯一索引,因此CB不参与此类操作。注意:在InnoDB中,NULLs始终是群集且唯一的,不能(?)拥有INSERT

    批量加载...我发现100行INSERTs的运行速度是100个LOAD DATA的10倍。 (这是由于解析等原因)但是在低级别,批量插入或INSERT ... ON DUPLICATE KEY UPDATE只是一堆单独的插入。因此,上述讨论适用。

    奖金回答......

    “IODKU”(REPLACE)几乎遵循上面的1..5步骤。在定位要更新的行时,它会发现是更新还是插入,然后相应地进行。

    DELETE实际上是UPDATE的简写加上REPLACE。但请注意此异常...如果表上有两个唯一键,则单行func pressedUserImage(_ sender: UITapGestureRecognizer) { ... } 可能会在插入1行之前删除2行。