Innodb 缓冲池和多个连接

Par*_*ars 3 mysql innodb performance join

假设我们有 10 亿条记录,并希望通过 post_type将它们存储在OneThree表中。

post_id   -> primary key  
post_type -> ( page, group, user )
user_id   -> index
date      -> index
Run Code Online (Sandbox Code Playgroud)

注意:我们有足够的 RAM 来存储缓冲池中的所有数据。( 大约 40 GB )
在我们的情况下,Reading数据库太多了

问题是:WHILE整个数据为ON缓冲池(RAM),有什么不同in performance3分离表和Join他们,或有1大表,并Select从它没有任何Join

在某些情况下,我们最好为其他类型的轻型查询使用单独的表。
但我们害怕JOINS

Rol*_*DBA 5

InnoDB 架构

InnoDB 架构

请记住进入InnoDB 缓冲池的内容

  • 已访问表的 16KB 数据页
  • 已访问索引的 16KB 索引页
  • 对二级索引的更改(在高写入环境中可能占用多达 50% 的缓冲池)

MySQL 的 JOIN 思想

信不信由你,无论您有一个大表并处理 WHERE 子句,还是您有多个连接,查询处理都具有相同的机械行为。(我在一年前写过这篇文章:JOIN 条件和 WHERE 条件之间是否存在执行差异?)您还可以在MySQL 文档中找到这一点。

你说你害怕 JOIN。MySQL 将每个查询都视为 JOIN。在帖子中引用的那本书SELECT将单个表上的 a 称为退化连接。多个表只使用一些额外的资源(文件句柄、临时表)。

对 InnoDB 缓冲池的影响

包含所有所需字段的单个表将被加载到缓冲池中,并且最多可以生成 1 个临时表来收集满足 where 子句的数据。另一方面,拥有单个表意味着非规范化数据并将冗余数据引入缓冲池以及物理表存储。

进行连接实际上可能会导致创建多个表。这也会将数据和相关索引加载到缓冲池中。对数据的任何后续访问实际上都可能发生在临时表中。不再需要访问缓冲池。

调音

虽然大型缓冲池有助于查询的初始处理,但调整每个连接的设置会更有帮助。我想到的参数是

任何导致需要比设置更多空间的查询都可能触发将该缓冲区分页到磁盘。在某些地方,查询速度变慢会变得明显和感觉到。

对于 InnoDB 缓冲池,您的主要目标应该是让数据和索引页尽可能频繁地出现。避免使用单个非规范化表,否则可能会使缓冲池膨胀。

对于查询,如果您害怕连接,您可能必须运行较小的查询。相反,您可以调整查询并设置更好的索引。

MySQL 5.6

如果您使用的是 MySQL 5.6,我会进一步建议通过运行此将 InnoDB 缓冲池的映射刷新到磁盘

SET GLOBAL innodb_buffer_pool_dump_now = 1;
Run Code Online (Sandbox Code Playgroud)

每一分钟。

将此添加到 my.cnf

[mysqld]
innodb_buffer_pool_load_at_startup=1
innodb_buffer_pool_dump_at_shutdown=1
Run Code Online (Sandbox Code Playgroud)

并重新启动mysql。

这样做将使所有数据和索引页在每次重新启动 mysql 时都可用。这使您可以在 RAM 中拥有最新的数据和索引,从而为每个查询提供便利。