我们在生产环境中看到了大量的SHOW TABLES;
查询DESCRIBE `table name`;
——不仅仅是在 Rails 服务器重启时。我们注意到它仅适用于我们的分区表。这是在 Rails 3.1.1 上 - 未在其他版本上测试。
在开发控制台(使用cache_classes = true
)中进行测试时,我们注意到对于分区模型,Rails 对从任何 find 方法返回的每条记录SHOW TABLES;
运行一个和一个。DESCRIBE `table name`;
例如,如果items
已分区,并Item.limit(5)
返回 5 条记录,mySQL 日志如下所示(注意:Rails 日志中不包含SHOW TABLES
AND ):DESCRIBE
SELECT `items`.* FROM `items` LIMIT 5;
SHOW TABLES;
DESCRIBE `items`;
SHOW TABLES;
DESCRIBE `items`;
SHOW TABLES;
DESCRIBE `items`;
SHOW TABLES;
DESCRIBE `items`;
SHOW TABLES;
DESCRIBE `items`;
这太疯狂了。
非分区模型不做任何SHOW TABLES
' 和DESCRIBE
',当然除了在启动 Rails 服务器时。看起来如果 AR 模型不知道它的主键,AR 必须在每次实例化该模型的对象时获取模式。
如果cache_classes
设置为true
,您会认为 Rails 会/应该缓存模式,即使是没有已知主键的模型。但事实并非如此。
您不会这么认为,SHOW TABLES
并且DESCRIBE
会对系统产生任何实际影响,但我们发现在足够大的流量下,由于对一个分区表的这些额外查询导致的并发读取会导致真正的性能问题。
我们怎样才能摆脱这些查询?