Índice para múltiples columnas en ActiveRecord


En ActiveRecord hay dos formas de declarar índices para múltiples columnas:

add_index :classifications, [:species, :family, :trivial_names]
add_index :classifications, :species
add_index :classifications, :family
add_index :classifications, :trivial_names

¿Hay alguna diferencia entre el primer enfoque y el segundo? Si es así, ¿cuándo debo usar el primero y cuándo el segundo?

Author: Ian Elliott, 2009-06-26

3 answers

Está comparando un índice compuesto con un conjunto de índices independientes. Son simplemente diferentes.

Piénselo de esta manera: un índice compuesto le da una búsqueda rápida del primer campo en un conjunto anidado de campos seguido de una búsqueda rápida del segundo campo solo dentro de los registros ya seleccionados por el primer campo, seguido de una búsqueda rápida del tercer campo-nuevamente, solo dentro de los registros seleccionados por los dos índices anteriores.

Tomemos un ejemplo. Su database engine no tomará más de 20 pasos para localizar un valor único dentro de 1,000,000 registros (si la memoria sirve) si está utilizando un índice. Esto es cierto si está utilizando un índice compuesto o independiente, pero SOLO para el primer campo ("especie" en su ejemplo, aunque creo que querría Familia, Especie y luego Nombre Común).

Ahora, digamos que hay 100,000 registros coincidentes para este primer valor de campo. Si solo tiene índices individuales, entonces cualquier búsqueda dentro de estos registros tomará 100,000 pasos: uno por cada registro recuperado por el primer índice. Esto se debe a que el segundo índice no se utilizará (en la mayoría de las bases de datos, esto es un poco una simplificación) y se debe usar una coincidencia de fuerza bruta.

Si tiene un índice compuesto entonces su búsqueda es mucho más rápida porque su segunda búsqueda de campo tendrá un índice dentro de el primer conjunto de valores. En este caso, no necesitarás más de 17 pasos para llegar a tu primera coincidencia valor en el campo 2 dentro de los 100,000 partidos en el campo 1 (log base 2 de 100,000).

Entonces: pasos necesarios para encontrar un registro único de una base de datos de 1,000,000 registros utilizando un índice compuesto en 3 campos anidados donde el primero recupera 100,000 y el segundo recupera 10,000 = 20 + 17 + 14 = 51 pasos.

Pasos necesarios en las mismas condiciones con índices independientes = 20 + 100,000 + 10,000 = 110.020 pasos.

Gran diferencia, ¿eh?

Ahora, no te vuelvas loco poniendo índices compuestos por todas partes. En primer lugar, son caros en inserciones y actualizaciones. En segundo lugar, solo se utilizan si realmente está buscando entre los datos anidados (para otro ejemplo, los uso al extraer datos para inicios de sesión de un cliente en un rango de fechas determinado). Además, no valen la pena si está trabajando con conjuntos de datos relativamente pequeños.

Finalmente, revise la documentación de su base de datos. Las bases de datos se han vuelto extremadamente sofisticadas en la capacidad de implementar los días y el escenario de la Base de Datos 101 que describí anteriormente pueden no mantenerse para algunos (aunque siempre me desarrollo como si lo hiciera solo para saber lo que estoy obteniendo).

 88
Author: Mark Brittingham,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-07-25 09:42:37

Los dos enfoques son diferentes. El primero crea un índice único en tres atributos, el segundo crea tres índices de un solo atributo. Los requisitos de almacenamiento serán diferentes, aunque sin distribuciones no es posible decir cuál sería más grande.

Indexar tres columnas [A, B, C] funciona bien cuando necesita acceder a los valores de A, A+B y A+B + C. No será bueno si su consulta (o condiciones de búsqueda o lo que sea) no hace referencia a A.

Cuando A, B y C son indexados por separado, algunos optimizadores de consultas DBMS considerarán la combinación de dos o más índices (sujeto a la estimación de eficiencia del optimizador) para dar un resultado similar a un solo índice de varias columnas.

Supongamos que tiene algún sistema de comercio electrónico. Desea consultar los pedidos por purchase_date, customer_id y a veces ambos. Empezaría creando dos índices: uno para cada atributo.

Por otro lado, si siempre especifica purchase_date y customer_id, entonces una sola el índice en ambas columnas sería probablemente el más eficiente. El pedido es significativo: si también desea consultar pedidos para todas las fechas de un cliente, haga que customer_id sea la primera columna del índice.

 10
Author: Mike Woodhouse,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-06-26 13:40:30

De los documentos:

Al crear un índice en múltiples columnas, la primera columna se utiliza como un nombre para el índice. Por ejemplo, cuando se especifica un índice en dos columnas [: first,: last], el DBMS crea un índice para ambas columnas, así como un índice de la primera columna: primero. Usando solo el primer nombre para esto índice tiene sentido, porque nunca tener que crear un índice singular con este nombre.

Utilice el primer método cuando crear un índice compuesto, y el segundo cuando se crean índices en atributos individuales.

Hay algunos puntos buenos aquí sobre cuándo usar índices compuestos, pero la esencia es que son buenos cuando se utiliza un dónde en múltiples atributos. Tenga en cuenta que deben usarse junto con otros índices (siempre indexe sus claves foriegn), no como un reemplazo.

 1
Author: Codebeef,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-06-26 13:17:32