mysql 如何处理涉及 myisam 和 innodb 表的查询?

Boo*_*ean 5 mysql innodb myisam join

在我们的mysql数据库中,我们同时使用myisam和innodb表,尽管还有更多的myisam表。

问题

  • 如果查询同时涉及myisam和innodb表,查询对innodb表使用表锁还是行锁?
  • 这是一个好的做法吗?

Rol*_*DBA 3

执行 JOIN 查询的三个方面可能会令人担忧

第 1 方面:锁定行为

每当存在涉及 MyISAM 和 InnoDB 的联接时,InnoDB 表最终将在表级锁定方面表现得像 MyISAM,而不是正常的行级锁定。MVCCACID 合规性无法应用于 MyISAM 数据。InnoDB 表也可能停滞不前。

第 2 方面:MyISAM 的参与

如果通过 INSERT、UPDATE 或 DELETE 更新任何 MyISAM 表,JOIN 查询中涉及的 MyISAM 表将被其他数据库连接锁定,从而强制 JOIN 查询等待,直到可以读取 MyISAM 表。鉴于此,如果在 JOIN 查询中混合使用 InnoDB 和 MyISAM,则 InnoDB 表将受到 PRIMARY KEY 条目(在聚集索引中)的间歇性锁定的影响。

请记住,MVCC 仍然允许READ-UNCOMMITTED事务REPEATABLE-READ正常工作,并让某些数据视图可用于其他事务。对于 READ-COMMITTED 和 SERIALIZABLE 事务则不能这样说

第 3 方面:查询优化器的 JOIN 视图

MyISAM

MySQL 将依靠表的索引基数来确定优化的 EXPLAIN 计划。MyISAM 表的索引基数通常是稳定的,直到它被 INSERT、UPDATE 和 DELETE 淹没为止。因此,您需要定期OPTIMIZE TABLE针对 MyISAM 表运行。

数据库

InnoDB 的索引基数永远不稳定!如果您运行SHOW INDEXES FROM innodbtable;,您将在每次运行该命令时看到索引基数发生变化。这是因为 InnoDB 将深入索引来估计基数。即使您OPTIMIZE TABLE针对 InnoDB 表运行,也只会对表进行碎片整理。OPTIMIZE TABLEANALYZE TABLE在内部运行以生成针对表的索引统计信息。这适用于 MyISAM。InnoDB 通常会忽略它。您可以禁用innodb_stats_on_metadata以获得稳定的 EXPLAIN 计划,但这只会导致您像对 MyISAM 表一样对 InnoDB 表进行 ANALYZE TABLE 维护。

结语

不管你相信与否,在 SELECT FOR UPDATE 期间仍然存在关于 InnoDB/MyISAM 加入的开放票证。如果你读过它,它总结了如下解决方案:请不要混合 InnoDB 和 MyISAM 进行连接