¿Agregar índice en la columna de bits ralentiza significativamente las inserciones?

11

Tengo una tabla con aproximadamente 1 millón a 5 millones de registros. Una pequeña parte de esos registros tiene una columna de bit establecida en 'VERDADERO'. Necesito encontrar rápidamente esos registros. Creo que ese índice puede acelerar la búsqueda en esta columna, pero tengo miedo de INSERT. De ahí mi pregunta.

La base de datos funciona como una especie de almacén de datos, por lo que hay muchos SELECT y pequeños (hasta 10-20 por día) pero INSERTs bastante grandes (hasta 200 mil registros a la vez). Me temo que las importaciones a la base de datos son más largas.

marioosh
fuente
55
¿Qué versión de SQL Server? Si 2008+ suena como un índice filtrado, podría ser lo que necesita.
Martin Smith
SQL Server 2005
marioosh
1
Puede dividir la tabla (agregue una nueva tabla con solo una columna, el PK de la tabla, que se completará con solo aquellas filas en las que la columna de bits es verdadera; al final, incluso podría eliminar la columna de bits). view funcionaría, también en 2005, con la falta de índices parciales.
ypercubeᵀᴹ
Tenga cuidado con la Vista indexada, ya que mencionó que tiene 10-20 insertos grandes por día, el mantenimiento de la Vista indexada podría superar el beneficio de la ganancia de rendimiento. No creo que haya ninguna "característica lista para usar" de SQL 2005 que pueda utilizar para mejorar su situación. pero si enumera la estructura de la tabla actual y el índice existente, podemos encontrar algunos diseños alternativos.
Anup Shah

Respuestas:

8

Un índice en un bit para 1 millón de registros es inútil. El optimizador nunca lo usará, solo pagará por mantenerlo. Una alternativa mucho mejor es agregar este bit como la tecla más a la izquierda en el índice agrupado.

Pero haré un disparo a ciegas en la oscuridad y supongo que lo que tiene es un patrón de cola: los registros se sueltan en la tabla con el bit establecido en 'VERDADERO' (es decir, 'necesita procesamiento = verdadero') y luego se ve un proceso en segundo plano. para estos registros, procesa un poco y actualiza el bit a FALSE. Este es un patrón omnipresente, también conocido cariñosamente como el 'patrón de receta de desastre de rendimiento'. Recomendaría colocar los registros en la tabla y colocar una notificación (podría ser tan simple como la ID de registro recién insertada), al mismo tiempo, en una cola . Consulte Uso de tablas como colas .

Remus Rusanu
fuente
1
No veo ningún buen punto para poner la columna de bits en el lado izquierdo, ya que no conocemos otras columnas de filtro con un usuario de alta cardinalalidad. Hasta ahora he visto la columna BIT es la última opción en el índice agrupado. pero sí, +1 para la buena referencia de "Usar tabla como colas".
Anup Shah
2
En realidad ejecuté una prueba y sí, usará el índice. Cree una tabla (identidad de identificación, bit myBit) agregue 100 filas donde el bit es 0 y 2000000 donde el bit es 1. Asegúrese de que las estadísticas estén actualizadas (si es necesario) y ejecute una consulta en myBit = 0 y se utilizará el índice.
Kenneth Fisher
@KennethFisher, excepto que en el patrón típico de alta velocidad de insertar VERDADERO / actualizar a FALSO inmediatamente, las estadísticas siempre estarán desactualizadas. Si prefiere jugar a la ruleta rusa con el optimizador en lugar de hacer un diseño claro, obtendrá lo que se merece ...
Remus Rusanu
"nunca lo usaré", esa afirmación es válida para el 99% de los casos, pero no sabemos en qué caso se encuentra el OP. He indexado con éxito en bit. Existen casos de uso.
usr
pregunta: la respuesta aquí es incorrecta, específicamente> "Cuando indexa un campo de bits (o algún rango estrecho), solo reduce el conjunto de trabajo por el número de filas que coinciden con ese valor. Si tiene un pequeño número de filas que lo coinciden reduciría mucho su conjunto de trabajo . Para una gran cantidad de filas con una distribución 50/50, podría generarle una ganancia de rendimiento muy pequeña en comparación con mantener el índice actualizado ". En cuyo caso, un índice en un bit que coincida con el 1% de los registros evitaría la necesidad de escanear el 99% de 1 millón para obtener un impulso significativo.
drzaus
2

Como dijo @MartinSmith, si alguna vez actualiza a SQL 2008, entonces un índice filtrado sería la solución perfecta. Sin embargo, mientras tanto, como caso general, CUALQUIER índice agregado aumentará su tiempo de carga. Índices pequeños menos que los grandes.

Una cosa que miraría es si tiene un índice existente que pueda modificarse. Suponiendo que sus consultas existentes estén usando un índice dado, luego agregar la columna de bits al final de ese índice debería tener un efecto mínimo en las inserciones y el efecto positivo que está buscando en sus consultas.

Lo siguiente a considerar es "¿Tengo muchos índices ya?" No hay una regla estricta sobre qué es "mucho", pero generalmente sigo una regla de 10 índices que es el límite a menos que REALMENTE necesite uno nuevo.

Último pensamiento, pruébelo en una instancia de prueba. Configure una tabla con unos pocos millones de filas, ejecute su carga sobre ella, agregue su índice y luego ejecute su carga nuevamente y vea si nota un aumento significativo en el tiempo de carga.

Solo usted realmente puede decidir qué es "significativo". Tengo máquinas en las que agregar 5 minutos al tiempo de carga es "significativo" y otras en las que podría ver con seguridad un aumento de un par de horas.

EDITAR:

Otra opción es dividir su tabla. Puede que tenga que usar una vista particionada si no está utilizando la edición Enterprise, pero aun así debería ayudar. Pones tus bits 0 en una partición y tus bits 1 en otra. Suponiendo que solo está insertando una versión u otra, incluso puede acelerar sus inserciones.

Kenneth Fisher
fuente