J'ai une question sur la base de données Rails.
Dois-je ajouter "index (unique)" à la colonne "id" créée automatiquement?
Si j'ajoute l'index à deux clés étrangères à la fois (add_index (:users, [:category, :state_id])
, que se passe-t-il? En quoi est-ce différent de l'ajout de l'index pour chaque clé?
class CreateUsers < ActiveRecord::Migration
def self.up
create_table :users do |t|
t.string :name
t.integer :category_id
t.integer :state_id
t.string :email
t.boolean :activated
t.timestamps
end
# Do I need this? Is it meaningless to add the index to the primary key?
# If so, do I need :unique => true ?
add_index :users, :id
# I don't think I need ":unique => true here", right?
add_index :users, :category_id # Should I need this?
add_index :users, :state_id # Should I need this?
# Are the above the same as the following?
add_index (:users, [:category, :state_id])
end
end
Excellente réponse jusqu'à présent. Question supplémentaire.
Dois-je ajouter "index" à toutes les clés étrangères comme "xxx_id"?
Ce serait mieux, car cela accélère la recherche dans le tri dans cette colonne. Et les clés étrangères sont quelque chose de très recherché.
Depuis la version 5 de Rails l'index sera créé automatiquement, pour plus d'informations, voir ici .
Dois-je ajouter "index" à la colonne "id" créée automatiquement?
Non, c'est déjà fait par Rails
Dois-je ajouter "index (unique)" à la colonne "id" créée automatiquement?
Non, comme ci-dessus
Si j'ajoute l'index à deux clés étrangères à la fois (
add_index (:users, [:category_id, :state_id])
, que se passe-t-il? En quoi est-ce différent de l'ajout de l'index pour chaque clé?
L'index est alors un index combiné des deux colonnes. Cela n'a aucun sens, sauf si vous voulez toutes les entrées pour un category_id
[~ # ~] et [~ # ~] un state_id
(CA devrait etre category_id
pas category
) en même temps.
Un index comme celui-ci accélérerait la demande suivante:
# Rails 2
User.find(:all, :conditions => { :state_id => some_id, :category_id => some_other_id })
# Rails 3
User.where(:state_id => some_id, :category_id => some_other_id)
Où
add_index :users, :category_id
add_index :users, :state_id
accélérera ces demandes:
# Rails 2+3
User.find_by_category_id(some_id)
User.find_by_state_id(some_other_id)
# or
# Rails 2
User.find(:all, :conditions => {:category_id => some_id})
User.find(:all, :conditions => {:state_id => some_other_id})
# Rails 3
User.where(:category_id => some_id)
User.where(:state_id => some_other_id)
Je devrais ajouter "index avec unique" pour xxx_id, non?
Non, car si vous faites cela, un seul utilisateur peut être dans une catégorie, mais le sens de la catégorie est que vous pouvez mettre plus plusieurs utilisateurs en un Catégorie. Dans votre modèle User
, vous avez quelque chose comme ça belongs_to :category
et dans votre modèle de catégorie quelque chose comme has_many :users
. Si tu as un has_many
relation la foreign_key
le champ ne doit pas être unique!
Pour des informations plus détaillées à ce sujet, vous devriez jeter un œil à tadman 's great answer .
L'indexation peut être une chose délicate et subtile, mais il existe des règles générales qui peuvent faciliter la détermination de l'utilisation.
La première chose à retenir est que les index peuvent fonctionner de plusieurs manières. Un index sur A, B, C fonctionne également pour A, B et simplement A, vous pouvez donc concevoir vos index pour qu'ils soient plus polyvalents si vous les commandez correctement. L'annuaire est indexé sur Nom, Prénom, de sorte que vous pouvez rechercher facilement des personnes par leur nom de famille ou une combinaison de nom et prénom. Vous ne pouvez cependant pas les rechercher directement par leur prénom. Vous auriez besoin d'un index distinct pour cela. Il en va de même pour le numéro de téléphone, que vous devrez également indexer.
Dans cet esprit, il existe de nombreuses choses qui dicteront la façon dont vous créez des index:
belongs_to
-has_many
appariement des relations, vous devez avoir un index sur la clé étrangère utilisée.has_many :through
, votre table de jointure doit avoir un index unique sur les deux propriétés impliquées dans la jointure en tant que clé composée.has_many
relation utilisant une étendue, assurez-vous qu'il existe un index qui inclut le has_many
clé étrangère et la colonne d'étendue dans cet ordre.Le but des index est d'éliminer les redoutables "analyses de table" ou "tri de fichiers" qui se produisent lorsque vos données ne sont pas indexées correctement.
En termes simples, examinez les requêtes générées par votre application et assurez-vous que les colonnes référencées dans les conditions WHERE
ou HAVING
et ORDER BY
les clauses sont représentées dans cet ordre.
add_index :users, :email, unique: true
)order by [a, b]
Ou find where( a and b )
, alors vous avez besoin d'un double index:Exemple concret:
Si tu as:
default_scope :order => 'photos.created_at DESC, photos.version DESC'
Vous devez ajouter:
add_index :photos, [:created_at, :version]
Remarque: Un index prend de l'espace supplémentaire sur le disque et ralentit la création et la mise à jour de chaque enregistrement, car il doit reconstruire chaque index.
Crédit:
https://tomafro.net/2009/08/using-indexes-in-Rails-choosing-additional-indexes , Rails - created_at lors de la commande de l'utilisateur, si vous ajoutez un index au tableau? , et les réponses ci-dessus.