15

我正在使用 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))

……和……</p>

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 次,总共花费 145 毫秒和 135 毫秒(分别)。

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

…以 104ms 的成本执行了 2 次,并且…</p>

SHOW search_path

…在一次通话中要求 45 毫秒。

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


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

4

4 回答 4

10

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

在开发模式下,它会在每次访问模型时查找这些值,因此如果您最近进行了更改,Rails 会知道。在生产模式下,Rails 会缓存这些内容,因此您看到这些内容的频率会大大降低,因此这真的不是问题。

于 2013-02-04T19:59:52.747 回答
3

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

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

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

于 2013-02-04T19:59:14.120 回答
0

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

Apartment 的人在 0.25.0 版本中修复了它。

于 2014-07-20T15:12:16.570 回答
-5

查询是从您的应用程序中的用户输入生成的吗?如果是这样,如果您没有控制用户输入,那么可能是有人试图破解您的应用程序的 sql 注入。

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

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

于 2013-02-04T19:55:08.787 回答