在Rails / Heroku上对Postgres数据库的意外SQL查询

我正在使用NewRelic向我的一个Rails应用程序发出一个非常长的请求,发现一些看起来完全是外来的SQL查询占用了相当长的时间。 我已经谷歌了,但我空洞地说出它们是什么,更不用说我是否可以防止它们发生。

SELECT COUNT(*) FROM pg_class c LEFT JOIN pg_namespace n ON n.oid = c.relnamespace WHERE c.relkind in (?, ?) AND c.relname = ? AND n.nspname = ANY (current_schemas(false)) 

…和…

 SELECT a.attname, format_type(a.atttypid, a.atttypmod), pg_get_expr(d.adbin, d.adrelid), a.attnotnull, a.atttypid, a.atttypmod FROM pg_attribute a LEFT JOIN pg_attrdef d ON a.attrelid = d.adrelid AND a.attnum = d.adnum WHERE a.attrelid = ?::regclass AND a.attnum > ? AND NOT a.attisdropped ORDER BY a.attnum 

…每次发生7次,共计145ms和135ms。

 SELECT DISTINCT(attr.attname) FROM pg_attribute attr INNER JOIN pg_depend dep ON attr.attrelid = dep.refobjid AND attr.attnum = dep.refobjsubid INNER JOIN pg_constraint cons ON attr.attrelid = cons.conrelid AND attr.attnum = cons.conkey[?] WHERE cons.contype = ? AND dep.refobjid = ?::regclass 

……以104毫秒的成本进行了2次,并且……

 SHOW search_path 

……一次通话命令45ms。

我的直觉说这些与Postgres Rails适配器有关,但我不明白是什么触发了它们或者它们正在做什么,或者(更重要的是)它们在典型请求中被解雇的原因。


我只是更彻底地检查了日志,看起来这个请求运行的Dyno在几秒钟之前已经转换为“up”,所以很可能这个请求是第一个。

表pg_class,pg_attribute,pg_depend等都描述了postgres中的表,列和依赖项。 在Rails中,模型类由表定义,因此Rails读取表和列以确定每个模型的属性。

在开发模式下,它会在每次访问模型时查找这些值,因此如果您最近发生了变化,Rails就会知道它。 在生产模式下,Rails会缓存它,因此您可以更频繁地看到这些,因此它确实不是一个问题。

这些查询用于获取表和字段的“定义”,并且可能被框架用于在Ruby中自动生成模型和/或validation规则。 (例如“内省”)

没有使用Ruby和您正在使用的框架的经验,但我不希望这些查询来自SQL注入。

您可以在pgAdmin或psql中自己运行查询以显示它们正在生成的结果,并了解它们从数据库中获取的信息

当使用Apartment Gem与Postgres Schemas进行多租户时,我收到了这些查询。 显然,每个excluded_model(使用默认模式的模型)在每个请求中生成一个“pg_class”查询。

来自公寓的人将其固定在0.25.0版本中。

是从您的应用程序中的用户输入生成的查询? 如果是这样,如果你没有对用户输入的控制,那么也许这是一个试图破解你的应用程序的人的SQL注入。

http://en.wikipedia.org/wiki/SQL_injection

我不熟悉rails,所以我不知道它是否已经自动创建了你作为开发人员不知道的查询,但我不这么认为。