mysql - unico - Cuándo agregar los índices en una tabla en Rails
tamaño de indices mysql (3)
Tengo una pregunta sobre la base de datos de Rails.
- ¿Debo agregar "índice" a todas las claves foráneas como "xxx_id"?
- ¿Debería agregar "índice" a la columna "id" creada automáticamente?
¿Debería agregar "índice (único)" a la columna "id" creada automáticamente?
Si agrego el índice a dos claves foráneas a la vez (
add_index (:users, [:category, :state_id])
, ¿qué ocurre? ¿En qué se diferencia esto de agregar el índice para cada clave?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
Gran respuesta hasta el momento. Pregunta adicional
- Debo agregar "índice con único" para xxx_id, ¿verdad?
¿Debo agregar "índice" a todas las claves foráneas como "xxx_id"?
Sería mejor, porque acelera la búsqueda en la clasificación en esta columna. Y las claves foráneas son algo que se busca mucho.
¿Debería agregar "índice" a la columna "id" creada automáticamente?
No, esto ya está hecho por rieles
¿Debería agregar "índice (único)" a la columna "id" creada automáticamente?
No, lo mismo que arriba
Si agrego el índice a dos claves foráneas a la vez (
add_index (:users, [:category_id, :state_id])
, ¿qué ocurre? ¿En qué se diferencia esto de agregar el índice para cada clave?
Entonces el índice es un índice combinado de las dos columnas. Eso no tiene ningún sentido, a menos que desee todas las entradas para un category_id
AND one state_id
(Debe ser category_id
not category
) al mismo tiempo.
Un índice como este aceleraría la siguiente solicitud:
# 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)
Dónde
add_index :users, :category_id
add_index :users, :state_id
acelerará estas solicitudes:
# 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)
Debo agregar "índice con único" para xxx_id, ¿verdad?
No, porque si haces esto, solo un usuario puede estar en una categoría, pero el significado de la categoría es que puedes poner más usuarios en una categoría. En su modelo de User
, tiene algo así como belongs_to :category
y en su modelo de Categoría algo así como belongs_to :category
has_many :users
. Si tiene una relación has_many
, el campo foreign_key
no debe ser único.
Para obtener información más detallada sobre esto, debería echar un vistazo a la gran answer tadman .
La indexación puede ser algo complicado y sutil, pero existen reglas generales aplicables que pueden facilitar la determinación de qué utilizar.
Lo primero que debe recordar es que los índices pueden funcionar en más de una forma. Un índice en A, B, C también funciona para A, B y simplemente A, por lo que puede diseñar sus índices para que sean más versátiles si los ordena correctamente. La guía telefónica está indexada en Apellido, Nombre, para que pueda buscar personas fácilmente por su apellido o una combinación de apellido y nombre. Sin embargo, no puede buscarlos directamente por su primer nombre. Necesitarías un índice separado para eso. Lo mismo vale para el número de teléfono, que también debería indexar.
Con eso en mente, hay muchas cosas que dictarán cómo crear índices:
- Si tiene una pareja de relaciones
belongs_to
-has_many
, debe tener un índice en la clave externa utilizada. - Si solicita sus registros, y hay un gran número de ellos que serán paginados, debe agregar esa columna de pedido al final del índice.
- Si tiene una relación
has_many :through
, su tabla de unión debe tener un índice único en ambas propiedades involucradas en la combinación como una clave compuesta. - Si obtiene un registro directamente utilizando un identificador único como nombre de usuario o correo electrónico, ese debería ser un índice único.
- Si obtiene conjuntos de registros de una relación
has_many
utilizando un ámbito, asegúrese de que haya un índice que incluya la clave externahas_many
y la columna del alcance en ese orden.
El objetivo con los índices es eliminar las temidas operaciones de "escaneo de tabla" u "clasificación de archivos" que ocurren cuando sus datos no están indexados correctamente.
En términos simples, observe las consultas generadas por su aplicación y asegúrese de que las columnas a las que se hace referencia en WHERE
o HAVING
condiciones y las cláusulas ORDER BY
estén representadas en ese orden.
- Siempre indexe claves foráneas
- Siempre indexe las columnas que va a ordenar por
- Todos los campos únicos (para garantizar la exclusividad a nivel de base de datos. Ejemplo de migración:
add_index :users, :email, unique: true
) - Si ordena por dos cosas, o busca por dos cosas, por ejemplo:
order by [a, b]
ofind where( a and b )
, entonces necesita un índice doble:
Ejemplo concreto:
Si usted tiene:
default_scope :order => ''photos.created_at DESC, photos.version DESC''
Debe agregar:
add_index :photos, [:created_at, :version]
Nota: Un índice ocupa más espacio en el disco y hace que sea más lento crear y actualizar cada registro, porque tiene que reconstruir cada índice.
Crédito:
https://tomafro.net/2009/08/using-indexes-in-rails-choosing-additional-indexes , rails - created_at cuando el usuario solicita, ¿Debería agregar un índice a la tabla? y las respuestas anteriores