2010-08-18 23 views
10

Me pregunto qué es más rápido en SQL (específicamente SQL Server).¿Es más rápido verificar que una Fecha sea (no) NULA o compare un bit a 1/0?

que podría tener una columna anulable de tipo Fecha y compararlo con NULL, o podría tener una columna de fecha no anulable y una columna separada bit y comparar la columna de la bit a 1/0.

es la comparación de la columna bit va a ser más rápido?

+0

A menudo me he preguntado si – TimS

Respuesta

12

Para comprobar que una columna IS NULL Servidor SQL realmente solo verificará un bit de todos modos. Hay un BITMAP NULO almacenado para cada fila que indica si cada columna contiene un NULO o no.

+1

preguntando a la columna de bit que tiene un índice es más rápido que nulo en el tiempo de fecha y hora? – Omu

+2

@ChuckNorris: siempre que se use el índice, consultar el índice sería más rápido ya que SQL Server podría simplemente buscar directamente las filas de interés. Esto también sería cierto si la columna 'datetime' en sí misma estuviera indexada. –

1

El bit será más rápido como la carga ésimo bit de memoria cargar sólo 1 byte y la carga de la fecha se llevará a 8 bytes. La comparación en sí tomará el mismo tiempo, pero la carga del disco llevará más tiempo. A menos que use un servidor muy antiguo o necesite cargar más de 10^8 filas, no notará nada.

+0

SQL Server solo cargará páginas enteras de 8KB dentro y fuera de la memoria. –

2

En igualdad de condiciones, yo diría que el bit sería más rápido porque es un tipo de datos "más pequeño". Sin embargo, si el rendimiento es muy importante aquí (y supongo que es debido a la pregunta), entonces siempre debe hacer las pruebas, ya que puede haber otros factores como índices, caché que afectan esto.

Parece que usted está tratando de decidir sobre un tipo de datos de campo que registrará si un evento X ha sucedido o no. Entonces, ya sea una marca de tiempo (cuando X sucedió) o solo un bit (1 si X sucedió, de lo contrario 0). En este caso, estaría tentado de ir a la fecha ya que le da más información (no solo si ocurrió X, sino también cuándo), lo que probablemente sea útil en el futuro para los informes. Solo vaya contra esto si la ganancia de rendimiento menor realmente es más importante.

2

Respuesta corta, Si sólo tiene 1s y 0s algo así como el índice de mapa de bits 1,0 es súper rápido. Los valores nulos no están indexados en ciertas clases de SQL, por lo que 'es nulo' y 'no nulo' son lentos. Sin embargo, piense en la semántica de la entidad antes de repartir esto. Siempre es mejor tener una definición de tabla semántica, si sabes a qué me refiero.

La velocidad proviene de la capacidad de usar índices y no del tamaño de los datos en este caso.

Editar
Consulte la respuesta de Martin Smith. Eso tiene más sentido para sqlserver, me dejé llevar por Oracle DB, mi error aquí.

+2

La pregunta es sobre el servidor SQL. Los nulos se indexan en SQL Server a menos que elija configurar un índice filtrado para ignorarlos. Los valores nulos también se representan en el almacenamiento utilizando un BITMAP NULO, por lo que no estoy seguro de si habrá alguna diferencia. –

9

que acabo de hacer una prueba simple para esto:

DECLARE @d DATETIME 
     ,@b BIT = 0 

SELECT 1 
WHERE @d IS NULL 

SELECT 2 
WHERE @b = 0 

Los resultados reales del plan de ejecución muestran el cálculo como con exactitud el costo misma en relación con el lote.

Actual Execution Plan

Tal vez alguien puede separar esta diferencia, pero me parece que no hay ninguna diferencia.


pruebas más

SET DATEFORMAT ymd; 

CREATE TABLE #datenulltest 
(
    dteDate datetime NULL 
) 

CREATE TABLE #datebittest 
(
    dteDate datetime NOT NULL, 
    bitNull bit DEFAULT (1) 
) 

INSERT INTO #datenulltest (dteDate) 
SELECT CASE WHEN CONVERT(bit, number % 2) = 1 THEN '2010-08-18' ELSE NULL END 
FROM master..spt_values 

INSERT INTO #datebittest (dteDate, bitNull) 
SELECT '2010-08-18', CASE WHEN CONVERT(bit, number % 2) = 1 THEN 0 ELSE 1 END 
FROM master..spt_values 


SELECT 1 
FROM #datenulltest 
WHERE dteDate IS NULL 

SELECT 2 
FROM #datebittest 
WHERE bitNull = CONVERT(bit, 1) 


DROP TABLE #datenulltest 
DROP TABLE #datebittest 

Actual Execution Plan

dteDate IS NULL resultado:

IS NULL tooltip

bitNull = 1 resultado:

bitNull = 1

OK, por lo que esta prueba ampliada viene con las mismas respuestas una vez más.
Podríamos hacer esto todo el día; llevaría una consulta muy compleja averiguar cuál es más rápido en promedio.

+0

El optimizador de consultas determina el plan de ejecución que se utilizará en función de varias estrategias. El muestreo dinámico es uno de ellos. Si decide que una búsqueda de acceso directo a la tabla (escaneo de tabla completa) es eficiente que la búsqueda basada en índice, la usa. Esto es muy cierto si el volumen de datos es pequeño, pero si hay un gran volumen de datos, las estadísticas serían diferentes. – questzen

+0

@questzen define enorme – Omu

+1

Es difícil de medir, pero si consideramos que ambos escenarios obtendrán los datos para el filtro de la misma tabla, la mayoría de los cálculos se ejecutarán de la misma manera. Puedo probar esto también, tengan paciencia conmigo. – Codesleuth

Cuestiones relacionadas