数据库内存和磁盘工作分配

时间:2015-08-18 00:16:52

标签: mysql memory-management innodb clustered-index

我正在阅读关于索引和索引策略的电子书章节,我已经知道了很多这些方面,但我坚持在InnoDB中的聚簇索引,这里是引用:

  

群集为I / O绑定工作负载提供了最大的改进。如果   数据在内存中适合它访问的顺序   真的很重要,因此聚类不会带来太多好处。

我相信这是事实,但我怎么猜测数据是否适合内存?数据库如何决定何时在内存中处理数据,何时不在?

我们假设我们有一个表 Emp ,其中列 ID 名称电话填写了100 000条记录

例如,如果我将聚集索引放在 ID 列上,并执行此查询

SELECT * FROM Employee;

我如何知道这是否会使用聚集索引带来的好处?

它以某种方式相对于这个线程 Difference between In memory databases and disk memory database

但我不确定数据库的行为方式

1 个答案:

答案 0 :(得分:1)

您的示例可能是20MB。

"在记忆中"真的意味着"在InnoDB buffer_pool"中,其大小由innodb_buffer_pool_size控制,应该设置为可用 RAM的大约70%。

如果您的查询命中磁盘而不是在buffer_pool中找到缓存的所有内容,它将运行(这只是一个经验法则)10倍。

你在说什么"聚集索引"是误导。让我扭转局面......

  • InnoDB确实需要PRIMARY KEY
  • PK(根据MySQL中的定义)UNIQUE
  • 桌子上只能有一个PK。
  • PK可以是"自然"密钥由一个(或多个)列组成,这些列自然地“工作
  • 如果你没有"自然"选择,然后使用id INT UNSIGNED NOT NULL AUTO_INCREMENT
  • PK和数据存储在同一个BTree中。 (实际上是一个B +树。)这个导致" PK与数据"聚集在一起。

真正的问题不是某些东西是集群的,而是它是否缓存在RAM中。 (记住10倍RoT。)

  • 如果表很小,它将保留在缓存中(一旦触及所有块),因此避免磁盘命中。
  • 如果一个巨大的表的某个子集是" hot",它将倾向于保留在缓存中。
  • 如果你必须随机访问一张巨大的桌子,那么你会因为大量的磁盘点击而减速。 (将UUID用作PRIMARY KEY 其他类型的INDEX时会发生这种情况。)
  

数据库如何决定何时在内存中处理数据,何时不在?

那也是错误的'所有处理都在内存中。在逐块的基础上,表和索引的各个部分被移入/移出buffer_pool。块(在InnoDB中)是16KB。而buffer_pool是一个"缓存"这些街区。

SELECT * FROM Employee;

很简单,但成本很高。它的运作方式如下:

  1. "开"表Employee(如果尚未打开 - 另外一个'缓存'处理此问题。)
  2. 转到表格的开头。这涉及向下钻取PK的BTree的左侧到第一叶节点(块)。如果尚未缓存,则将其提取到buffer_pool中。
  3. 读一行 - 这将在该叶节点中。
  4. 读取下一行 - 这可能是 在同一个块中。如果没有,请到下一个'阻止(必要时从磁盘读取)。
  5. 重复步骤4,直至完成表格。
  6. 如果您有WHERE子句,事情会变得更有趣。然后它取决于是否涉及PK或其他INDEX

    Etc等。