商业智能人员要求更快的机器、最新的软件等,他的一些客户抱怨查询时间超过一个小时。该工具是 Cognos/Insight,数据库是主 MySQL 的复制副本,我们很快将迁移到 MariaDB。
我的直觉(在我弄脏 SQL 和执行计划之前)是我们只是在处理来自 Cognos 的优化不佳的查询和支持它们的不适当的索引集合。
我的问题是(在我定制解决方案之前):实时从表是否有公认的策略允许主表上不存在的索引?
商业智能人员要求更快的机器、最新的软件等,他的一些客户抱怨查询时间超过一个小时。该工具是 Cognos/Insight,数据库是主 MySQL 的复制副本,我们很快将迁移到 MariaDB。
我的直觉(在我弄脏 SQL 和执行计划之前)是我们只是在处理来自 Cognos 的优化不佳的查询和支持它们的不适当的索引集合。
我的问题是(在我定制解决方案之前):实时从表是否有公认的策略允许主表上不存在的索引?
在从服务器上启用慢速查询日志,
log_queries_not_using_indexes
应该能够确认你的直觉告诉你的是什么。您可以获取捕获的查询,EXPLAIN
对它们运行,并更好地记录您的怀疑。为了更直接地回答这个问题,在 slave 上声明未在 master 上声明的索引是绝对有效的。我建议这是一种常见的做法,也是副本对很多事情有用的众多原因之一。使用具有足够权限的帐户连接到从站,并直接在从站上更改表。
唯一的例外——这在直觉上应该是显而易见的,因为行数据需要在 master 和 replica 上保持一致——是你不能安全地
UNIQUE
在 slave 上不存在时声明约束或外键约束大师。这行不通,这很好,因为它无论如何都没有意义。还请记住,MySQL 中的索引具有名称,如果在添加索引时未提供名称,则名称会自动生成。一个好的做法可能是在副本上明确命名这些索引,以便将来添加到主服务器的索引不可能导致索引名称冲突,这会破坏复制。我的本地惯例是在索引名称前加上“ix_repl_”前缀,这当然永远不会在 master 上使用。
另请注意,正确的重复索引(其中完全相同的列,并且没有其他列包含在多个索引中)在 MySQL 5.6 中已弃用,并且在 MySQL 5.7 中默认情况下是不允许的,这显然可能在更高版本中导致复制停止如果您随后在主服务器上声明了相同的索引(即使名称不同)。这不会是一个关键问题(只要您正在监视复制——您是,对吗?)因为通过在重新启动从属 SQL 线程之前简单地删除副本上现在冗余的索引来重新启动复制是安全的。失败的事件将被重试,并且现在是有效的,因为没有冲突的索引,并且替换索引将建立在副本上。
旁注:请记住,MySQL 复制要求副本服务器上的 MySQL 版本与主服务器上的版本相同或更新...因此在升级(或迁移到 MariaDB)时,您几乎肯定会想要升级首先是副本,然后是主服务器。这样做的原因是较新的副本将了解较旧的主服务器的功能和怪癖,但较新的主服务器可能会在复制流中引入旧副本服务器无法解释的行为。这条规则有少数例外,但这绝对是规则。