Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/63.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 如何在Rails(使用postgres)中较低的(“用户”用户名)上创建索引_Ruby On Rails_Postgresql_Ruby On Rails 4_Indexing_Rails Activerecord - Fatal编程技术网

Ruby on rails 如何在Rails(使用postgres)中较低的(“用户”用户名)上创建索引

Ruby on rails 如何在Rails(使用postgres)中较低的(“用户”用户名)上创建索引,ruby-on-rails,postgresql,ruby-on-rails-4,indexing,rails-activerecord,Ruby On Rails,Postgresql,Ruby On Rails 4,Indexing,Rails Activerecord,我的userscoontroller#create操作中发生了顺序扫描 SELECT ? AS one FROM "users" WHERE (LOWER("users"."username") = LOWER(?) AND "users"."id" != ?) LIMIT ? Explain plan 1 Query planLimit (cost=0.00..3.35 rows=1 width=0) 2 Query plan-> Seq Scan on users (cost=0.0

我的
userscoontroller#create
操作中发生了顺序扫描

SELECT ? AS one FROM "users" WHERE (LOWER("users"."username") = LOWER(?) AND "users"."id" != ?) LIMIT ?

Explain plan
1 Query planLimit (cost=0.00..3.35 rows=1 width=0)
2 Query plan-> Seq Scan on users (cost=0.00..3.35 rows=1 width=0)
3 Query planFilter: ?
我相当肯定,这源自以下模型验证:

验证:用户名,唯一性:{区分大小写:false}


我是否应该针对此express创建索引?如果是这样的话,在Rails 4中正确的方法是什么?

是的,验证将执行这种查询,而这种查询将执行表扫描

实际上,这里有几个问题:

  • 由于逻辑不在其所属的数据库中,因此验证受竞争条件的约束。数据库应负责所有数据完整性问题,而不考虑通常的Rails思想
  • 您的验证会触发表扫描,没有人喜欢表扫描
您可以使用一个索引解决这两个问题。第一个问题是通过在数据库中使用唯一的索引来解决的。第二个问题通过索引
lower(username)
而不是
username
的结果来解决

AFAIK Rails仍然不理解表达式上的索引,因此您必须做两件事:

  • schema.rb
    切换到
    structure.sql
    ,以防止Rails忘记索引。在
    config/application.rb
    中,您需要设置:

    config.active_record.schema_format = :sql
    
    您还必须开始使用
    db:structure:*
    rake任务,而不是
    db:schema:*
    任务。一旦切换到
    structure.sql
    ,就可以删除
    db/schema.rb
    ,因为它不再被更新或使用;您还需要在修订控制中开始跟踪
    db/structure.sql

  • 通过在迁移中编写一些SQL,手动创建索引。这很简单:

    def up
      connection.execute(%q{
        create index idx_users_lower_username on users(lower(username))
      })
    end
    
    def down
      connection.execute(%q{
        drop index idx_users_lower_username
      })
    end
    

  • 当然,这会给您留下一些特定于PostgreSQL的东西,但这没什么好担心的,因为ActiveRecord并没有提供任何有用的可移植性。

    我认为这是暗示,但只是为了验证,这是否意味着我应该删除
    schema.rb
    schema.rb
    一旦更改了
    schema\u格式
    ,就不会用于任何事情。是的,删除它并开始跟踪修订控件中的
    db/structure.sql
    。您的
    用户
    表有多大?仅仅因为你有一个索引并不意味着它会被使用。查询优化器将猜测索引是否值得,猜测取决于表中数据的外观、大小。。。如果只有100个条目,那么使用索引可能比全部检查要昂贵。查询优化是一门黑色艺术,明白了。当你回答的时候,我发现上面说的正是同一件事。在开发中,是的,用户不多。所以它要做一个全表扫描。但我认为,对于更大的数据集,在生产中使用它还是更好的。@Josh Smith确保运行
    真空分析用户创建索引后。