在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,所以我不知道它是否已经自动创建了你作为开发人员不知道的查询,但我不这么认为。