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

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

质询

>如果查询涉及myisam和innodb表,查询是否会对innodb表使用表锁或行锁?
>这是一个好习惯吗?

最佳答案
执行JOIN查询有三个方面可能会令人担忧

ASPECT#1:锁定行为

每当有涉及MyISAM和InnoDB的连接时,InnoDB表将在表级锁定方面表现得像MyISAM,而不是正常的行级锁定.MVCCACID compliance不能应用于MyISAM数据. InnoDB表也可能停滞不前.

ASPECT#2:MyISAM的参与

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

请记住MVCC will still allow READ-UNCOMMITTED and REPEATABLE-READ transactions to work just fine and let certain views of data be available for other transactions. The same cannot be said for READ-COMMITTED and SERIALIZABLE transactions.

ASPECT#3:查询优化器的JOIN视图

MyISAM数据

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

InnoDB的

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

结语

信不信由你,有still an open ticket on InnoDB/MyISAM joining during a SELECT FOR UPDATE.如果你读它,它总结了如下决议:请不要加入InnoDB和MyISAM的联合.

转载注明原文:mysql如何处理触及myisam和innodb表的查询? - 代码日志