¿No hay índices en tablas pequeñas?


"Deberíamos olvidarnos de las pequeñas eficiencias, digamos alrededor del 97% de las veces: la optimización prematura es la raíz de todo mal."(Donald Knuth). Es poco probable que mis tablas SQL contengan más de unos pocos miles de filas cada una (¡y esas son las grandes!). SQL Server Database Engine Tuning Advisor descarta la cantidad de datos como irrelevante. Así que ni siquiera debería pensar en poner índices explícitos en estas tablas. ¿Correcto?

Author: Milen A. Radev, 2008-10-31

13 answers

El valor de los índices está en lecturas de velocidad. Por ejemplo, si está haciendo muchas selecciones basadas en un rango de fechas en una columna de fecha, tiene sentido poner un índice en esa columna. Y, por supuesto, generalmente se agregan índices en cualquier columna que se va a unir con cualquier frecuencia significativa. La ganancia de eficiencia también está relacionada con la relación entre el tamaño de sus conjuntos de registros típicos y el número de registros (es decir, agarrar registros 20/2000 se beneficia más de la indexación que agarrar 90/100 registro). Una búsqueda en una columna no indexada es esencialmente una búsqueda lineal.

El costo de los índices viene en escrituras, porque cada INSERTO también requiere un inserto interno para cada índice de columna.

Entonces, la respuesta depende completamente de tu aplicación if si es algo así como un sitio web dinámico donde el número de lecturas puede ser 100x o 1000x las escrituras, y estás haciendo búsquedas frecuentes y dispares basadas en columnas de datos, la indexación puede ser beneficiosa. Pero si escribe en gran medida superan en número lee, entonces su ajuste debe centrarse en acelerar esas consultas.

Se necesita muy poco tiempo para identificar y comparar un puñado de las operaciones más frecuentes de su aplicación, tanto con como sin índices en las columnas JOIN/WHERE, le sugiero que lo haga. También es inteligente monitorear su aplicación de producción e identificar las consultas más caras y frecuentes, y centrar sus esfuerzos de optimización en la intersección de esos dos conjuntos de consultas (lo que podría significar índices o algo totalmente diferente, como asignar más o menos memoria para cachés de consulta o unión).

 31
Author: joelhardi,
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
2008-10-31 08:51:52

Las sabias palabras de Knuth no son aplicables a la creación (o no) de índices, ya que al agregar índices estás no optimizando nada directamente: estás proporcionando un índice que el optimizador DBMSs puede usar para optimizar algunas consultas. De hecho, podría argumentar mejor que decidir no indexar una tabla pequeña es una optimización prematura, ¡ya que al hacerlo restringe las opciones del optimizador DBMS!

Diferentes DBMSs tendrán diferentes pautas para elegir indizar o no las columnas en función de varios factores, incluido el tamaño de la tabla, y son estos los que deben considerarse.

Lo que es un ejemplo de optimización prematura en bases de datos: "desnormalización para el rendimiento" antes de cualquier benchmarking ha indicado que la base de datos normalizada realmente tiene problemas de rendimiento.

 8
Author: Tony Andrews,
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
2008-10-31 13:14:41

Las columnas de clave primaria se indexarán para la restricción única. Todavía indexaría todas las columnas de claves foráneas. El optimizador puede optar por ignorar su índice si es irrelevante.

Si solo tiene un poco de datos, el costo adicional para insertar/actualizar tampoco debería ser significativo.

 7
Author: WW.,
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
2008-10-31 08:46:03

Depende. Es la tabla una tabla de referencia?

Hay tablas de mil filas donde la ausencia de un índice, y los escaneos de tabla resultantes pueden marcar la diferencia entre una operación bastante simple retrasando al usuario por 5 minutos en lugar de 5 segundos. He visto exactamente este problema, usando un DBMS que no sea SQL Server.

Generalmente, si la tabla es una tabla de referencia, las actualizaciones sobre ella serán relativamente raras. Esto significa que el golpe de rendimiento para actualizar el índice también será relativamente raro. Si el optimizador pasa por encima del índice, el rendimiento alcanzado en el optimizador será insignificante. El espacio necesario para almacenar el índice también será insignificante.

Si declara una clave primaria, debería obtener un índice automático de esa clave. Ese índice automático casi siempre le hará suficiente bien para justificar su costo. Déjalo ahí. Si crea una tabla de referencia sin una clave primaria, hay otros problemas en su diseño metodologia.

Si realiza búsquedas frecuentes o uniones frecuentes en algún conjunto de columnas que no sea la clave primaria, un índice adicional podría pagarse por sí mismo. No arregles ese problema a menos que sea un problema.

Esta es la regla general: siga el comportamiento predeterminado del DBMS, a menos que encuentre una razón para no hacerlo. Cualquier otra cosa es una preocupación prematura con la optimización de su parte.

 5
Author: Walter Mitty,
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
2008-10-31 10:27:55

Le sugiero que siga las reglas habituales sobre indexación, que aproximadamente significa "crear índices en las columnas que utiliza en sus consultas".

Esto puede sonar innecesario con una base de datos tan pequeña. Como otros ya han dicho: mientras su base de datos se mantenga tan pequeña como ha descrito, las consultas serán lo suficientemente rápidas de todos modos, y los índices no son realmente necesarios. Incluso pueden ralentizar las inserciones y actualizaciones, pero a menos que tenga requisitos muy específicos allí, se no importa con una base de datos tan pequeña.

Pero, si la base de datos crece (lo que las bases de datos a veces tienden a hacer) no tiene que recordar agregar índices a esa base de datos antigua que probablemente haya olvidado para entonces. Tal vez incluso se ha instalado en uno de sus clientes, y no se puede modificar!

Supongo que lo que estoy diciendo es esto: los índices deben ser una parte tan natural del diseño de su base de datos, que es la falta de índices que es la optimización, prematura o no.

 4
Author: Thomas Padron-McCarthy,
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
2008-10-31 12:25:33

Absolutamente incorrecto. 100% incorrecto. No pongas un millón de índices inútiles, pero quieres una Clave Primaria (en la mayoría de los casos), y la quieres AGRUPADA correctamente.

He aquí por qué:

SELECT * FROM MySmallTable <-- No worries... Index won't help

SELECT
    *
FROM
    MyBigTable INNER JOIN MySmallTable ON... <-- Ahh, now I'm glad I have my index.

Aquí hay una buena regla para seguir.

"Dado que tengo una TABLA, es probable que quiera consultarla en algún momento... Si voy a consultarlo, es probable que lo haga de una manera consistente..."

EDITAR: Estoy agregando esta línea: Si tienes un ejemplo concreto en mente, te mostraré cómo indexarlo y cuánto ahorro obtendrás al hacerlo. Por favor, proporcione una tabla y un ejemplo de cómo planea usar esa tabla.

 4
Author: Timothy Khouri,
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
2011-09-07 19:46:11

Si las filas tienen un ancho estrecho, y unos pocos miles de filas caben en, por ejemplo, 10-20 páginas de 8K, es poco probable que el optimizador SQL elija usar un índice incluso si crea uno.

 3
Author: Mitch Wheat,
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
2008-10-31 08:24:47

Pon índices SOLO si tienes que:)
Hay momentos en los que poner índices realmente puede dañar el rendimiento, dependiendo de para qué se use la tabla...
Por lo tanto, en otras palabras, usted pensaría en poner índices en las tablas cuando sea necesario según lo determinado por el perfil de la aplicación.

 1
Author: Aleris,
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
2008-10-31 08:27:39

Los índices a menudo se crean implícitamente cuando se usan restricciones ÚNICAS. Yo no trataría de evitar su uso en ese caso!

 1
Author: Greg Hewgill,
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
2008-10-31 08:31:07

Como regla general, es bueno evitar índices más pequeños, ya que normalmente no se usarán.

Pero a veces pueden proporcionar un gran impulso como describí aquí.

 1
Author: Michael K. Campbell,
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
2008-11-04 01:02:09

Supongo que hay una indexación automática en la clave principal de la tabla que debería ser suficiente cuando se consulta en una tabla con menos datos.

Por lo tanto, sí se pueden evitar índices explícitos en caso de que haya un pequeño conjunto de datos para trabajar.

 0
Author: Nrj,
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
2008-10-31 08:24:53

Incluso si tiene un índice, es posible que SQL Server ni siquiera lo use, dependiendo de las estadísticas de esa tabla. Y si planea poner un índice para un informe que se ejecutará como máximo un par de veces al año, tenga en cuenta que las penalizaciones de INSERCIÓN/ACTUALIZACIÓN por agregar el índice estarán vigentes TODO EL TIEMPO. Antes de agregar un índice, pregúntese si vale la pena la penalización por rendimiento.

 0
Author: Maxam,
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
2008-10-31 12:45:41

Tiene que entender que basado en la consulta se pueden hacer dos búsquedas, una en el índice para obtener el puntero a la fila, la siguiente a la fila en sí. Si los datos que se están consultando están en las columnas de índice, puede que no sea necesario un paso adicional.

Es completamente posible que la doble inmersión de datos sea más lenta incluso si el optimizador va tras el índice. Si nos preocupamos o no depende de la elaboración de perfiles de aplicaciones y eventualmente explicar los planes.

 0
Author: Jé Queue,
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-10-30 03:27:01