相关疑难解决方法(0)

如何在带有Rails的WHERE子句中使用ANY而不是IN?

我曾经有过如下查询:

MyModel.where(id: ids)
Run Code Online (Sandbox Code Playgroud)

哪个生成sql查询如:

SELECT "my_models".* FROM "my_models"
WHERE  "my_models"."id" IN (1, 28, 7, 8, 12)
Run Code Online (Sandbox Code Playgroud)

现在我想改为使用ANY而不是IN.我创造了这个:

MyModel.where("id = ANY(VALUES(#{ids.join '),('}))"
Run Code Online (Sandbox Code Playgroud)

现在,当我使用空数组时,ids = []我得到以下错误:

MyModel Load (53.0ms)  SELECT "my_models".* FROM "my_models"  WHERE (id = ANY(VALUES()))
ActiveRecord::JDBCError: org.postgresql.util.PSQLException: ERROR: syntax error at or near ")"
ActiveRecord::StatementInvalid: ActiveRecord::JDBCError: org.postgresql.util.PSQLException: ERROR: syntax error at or near ")"
Position: 75: SELECT "social_messages".* FROM "social_messages"  WHERE (id = ANY(VALUES()))
    from arjdbc/jdbc/RubyJdbcConnection.java:838:in `execute_query'
Run Code Online (Sandbox Code Playgroud)

sql postgresql activerecord ruby-on-rails-3 ruby-on-rails-4

11
推荐指数
1
解决办法
1万
查看次数

使用 IN 和列表进行 SQL 查询非常慢

有没有办法优化这样的查询:

SELECT count(*) FROM mytable 
WHERE 
indexed_field IN ('v1', 'v2', ..., 'v2000')
AND NOT regular_field='something'
AND other_regular_field='something_else';
Run Code Online (Sandbox Code Playgroud)

这个查询“有效”。问题是它非常慢(1分钟以上)。我认为使用IN定义的列表来使用表达式就可以了,但事实证明并不是那么好。

我正在使用 Postgresql 9.6。

我的表有310K。

查询解释:

QUERY PLAN
Aggregate  (cost=396158.70..396158.71 rows=1 width=8) (actual time=8630.558..8630.559 rows=1 loops=1)
  ->  Seq Scan on mytable  (cost=0.00..396156.77 rows=772 width=0) (actual time=7853.840..8630.478 rows=916 loops=1)
        Filter: (((non_indexed_field)::text <> 'value1'::text) AND ((non_indexed_field)::text = 'value2'::text) AND ((indexed_field)::text = ANY ('{lots and lots of values....}'::text[])))
        Rows Removed by Filter: 306768
Planning time: 2.543 ms

Execution time: 8630.770 ms
Run Code Online (Sandbox Code Playgroud)

通过分析、缓冲:

Aggregate  (cost=396158.70..396158.71 …
Run Code Online (Sandbox Code Playgroud)

sql postgresql

1
推荐指数
1
解决办法
2975
查看次数