none
Comparación de tiempos en Actualizar una tabla con 2 columnas y otra con 25 columnas RRS feed

  • Pregunta

  • Hola amigos tengo una pregunta, tengo el siguiente escenario tengo una tabla con 2 columnas y otra con 25 columnas, en caso de actualizar una fila en cada caso, cual seria tiempo de cada una teniendo en cuenta todas las columnas y si la cantidad de columnas infiere en tiempo de procesamiento de tal actualización.

    gracias

    Saludos

    miércoles, 18 de abril de 2018 15:54

Todas las respuestas

  • Hola Diego:

    Te voy a plantear un supuesto

    CREATE TABLE PRUEBA1(COL1 INT, COL2 INT)
    GO
    CREATE TABLE PRUEBA2(C1 INT, C2 INT, C3 INT, C4 INT, C5 INT, C6 INT, C7 INT, C8 INT, C9 INT, C10 INT,C11 INT, C12 INT, C13 INT, C14 INT, C15 INT, C16 INT, C17 INT, C18 INT, C19 INT, C20 INT, C21 INT, C22 INT, C23 INT, C24 INT, C25 INT )
    GO
    
    INSERT INTO PRUEBA1 (COL1, COL2) VALUES (1,1)
    GO
    INSERT INTO PRUEBA2(C1 , C2 , C3 , C4 , C5 , C6 , C7 , C8 , C9 , C10 ,C11 , C12 , C13 , C14 , C15 , C16 , C17 , C18 , C19 , C20 , C21 , C22 , C23 , C24 , C25  )
    VALUES (1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5)
    GO
    
    DECLARE @TIEMPO DATETIME ;
    DECLARE @TIEMPODIFERENCIA DATETIME;
    DECLARE @TIEMPO2 DATETIME;
    DECLARE @TIEMPODIFERENCIA2 DATETIME;
    
    SET @TIEMPO = GETDAte();
    UPDATE PRUEBA1 SET COL1 = 2, COL2=2;
    SET @TIEMPODIFERENCIA =GETDATE();
    SET @TIEMPO2 = GETDATE();
    UPDATE PRUEBA2 SET  C1=2, C2=2, C3=2, C4=2, C5=2, C6=2, C7=2, C8=2, C9=2, C10=2, C11=2, C12=2, C13=2, C14=2, 
    C15=2, C16=2, C17=2, C18=2, C19=2, C20=2, C21=2, C22=2, C23=2, C24=2, C25=2 
    SET @TIEMPODIFERENCIA2 = GETDAte();
    
    
    SELECT @TIEMPO, @TIEMPODIFERENCIA, @TIEMPODIFERENCIA-@TIEMPO AS EJERCICIO1, @TIEMPO2, @TIEMPODIFERENCIA2, @TIEMPODIFERENCIA2-@TIEMPO2 AS EJERCICIO2

    Como verás en el supuesto y dado que datetime, tiene un intervalo de 3 milisegundos, no tiene porque ser más rapido una columna que 25, pero aunque así lo fuera, no crees que seguro que hay sitios muchisimo más efectivos donde puedes mejorar, en procesamiento y en rendimiento que en esa suposición.

    El correcto manejo de indices, crear las tablas apropiadas, consultas optimizadas, te darán una diferencia millones de veces mejor que pensar que porque reduzcas el procesamiento de update de 2 columnas a 25.

    Ojo esto era un ejemplo sencillo, porque a priori, parece que si te planteas eso es porque estas pensando en juntar 24 columnas en uno.

    Un buen diseño siempre será mucho más rápido, que lo que intentemos afinar en cosas que no podemos controlar.

    Si repites mi ejercicio 20 veces, cada una obtendrá resultados diferentes, eso sin estar en un servidor en producción.

    Un saludo

    miércoles, 18 de abril de 2018 16:20
  • Hola Diego esta información la puedes conocer corriendo un plan de ejecución, la cual te dará los costes estimados de tu transacción en la base de datos.

    Y aqui un tutorial sobre como interpretar estos resultados:

    http://devtroce.com/2011/08/04/tutorial-basico-para-interpretar-el-plan-de-ejecucion-de-sql-server/

    Saludos.


    Carlos Aldi


    • Editado Carlos Aldi miércoles, 18 de abril de 2018 16:21
    • Propuesto como respuesta Carlos Aldi jueves, 31 de mayo de 2018 17:53
    miércoles, 18 de abril de 2018 16:20
  • Para completar el ejercicio y dejando muchisimas cosas en el tintero,

    CREATE TABLE PRUEBA4(COL1 varchar(8000), COL2 varchar(8000))
    GO
    CREATE TABLE PRUEBA5(C1 varchar(8000), C2 varchar(8000), C3 varchar(8000), C4 varchar(8000), C5 varchar(8000), C6 varchar(8000), C7 varchar(8000), C8 varchar(8000), C9 varchar(8000), C10 varchar(8000),C11 varchar(8000), C12 varchar(8000), C13 varchar(8000), C14 varchar(8000), C15 varchar(8000), C16 varchar(8000), C17 varchar(8000), C18 varchar(8000), C19 varchar(8000), C20 varchar(8000), C21 varchar(8000), C22 varchar(8000), C23 varchar(8000), C24 varchar(8000), C25 varchar(8000) )
    GO
    create table PRUEBA6 (id int primary key identity (1,1),C1 varchar(8000), C2 varchar(8000), C3 varchar(8000), C4 varchar(8000), C5 varchar(8000), C6 varchar(8000), C7 varchar(8000), C8 varchar(8000), C9 varchar(8000), C10 varchar(8000),C11 varchar(8000), C12 varchar(8000), C13 varchar(8000), C14 varchar(8000), C15 varchar(8000), C16 varchar(8000), C17 varchar(8000), C18 varchar(8000), C19 varchar(8000), C20 varchar(8000), C21 varchar(8000), C22 varchar(8000), C23 varchar(8000), C24 varchar(8000), C25 varchar(8000) )
    GO
    
    DECLARE @CARACTER  VARCHAR(8000) = '1';
    DECLARE @CONTADOR INT=1;
    WHILE (@CONTADOR < 8000)
    BEGIN
    	INSERT INTO PRUEBA4(COL1, COL2) VALUES (@CARACTER,@CARACTER)
    
    	INSERT INTO PRUEBA5(C1 , C2 , C3 , C4 , C5 , C6 , C7 , C8 , C9 , C10 ,C11 , C12 , C13 , C14 , C15 , C16 , C17 , C18 , C19 , C20 , C21 , C22 , C23 , C24 , C25  )
    	VALUES (@CARACTER,@CARACTER,@CARACTER,@CARACTER,@CARACTER,@CARACTER,@CARACTER,@CARACTER,@CARACTER,
    	@CARACTER,@CARACTER,@CARACTER,@CARACTER,@CARACTER,@CARACTER,@CARACTER,@CARACTER,@CARACTER,@CARACTER,
    	@CARACTER,@CARACTER,@CARACTER,@CARACTER,@CARACTER,@CARACTER)
    
    	INSERT INTO PRUEBA6(C1 , C2 , C3 , C4 , C5 , C6 , C7 , C8 , C9 , C10 ,C11 , C12 , C13 , C14 , C15 , C16 , C17 , C18 , C19 , C20 , C21 , C22 , C23 , C24 , C25  )
    	VALUES (@CARACTER,@CARACTER,@CARACTER,@CARACTER,@CARACTER,@CARACTER,@CARACTER,@CARACTER,@CARACTER,
    	@CARACTER,@CARACTER,@CARACTER,@CARACTER,@CARACTER,@CARACTER,@CARACTER,@CARACTER,@CARACTER,@CARACTER,
    	@CARACTER,@CARACTER,@CARACTER,@CARACTER,@CARACTER,@CARACTER)
    	
    
    	SET @CARACTER=@CARACTER+@CARACTER; /*FORZAR EL ALMACENAMIENTO PARA QUE LAS PAGINAS SEAN DIFERENTES */
    	SET @CONTADOR = @CONTADOR +1; /*RECORRER EL BUCLE PARA FINALIZAR */
    END
    SELECT * fROM PRUEBA6
    /* observarás que los datos no tienen sentido, cosa que será la normalidad, porque en los campos de tipo caracter, que serán muchos, tu
    no puedes controlar las entradas del usuario */
    
    DECLARE @TIEMPO DATETIME ;
    DECLARE @TIEMPODIFERENCIA DATETIME;
    DECLARE @TIEMPO2 DATETIME;
    DECLARE @TIEMPODIFERENCIA2 DATETIME;
    DECLARE @TIEMPO3 DATETIME;
    DECLARE @TIEMPODIFERENCIA3 DATETIME;
    
    /* ahora vamos a incluir la lectura en disco */ 
    /*MUY IMPORTANTE AL TERMINAR PONER STATISTICS IO EN OFF */
    
    SET STATISTICS IO ON
    SET @TIEMPO = GETDAte();
    UPDATE PRUEBA4 SET COL1 = '2', COL2='2';
    SET @TIEMPODIFERENCIA =GETDATE();
    
    SET @TIEMPO2 = GETDATE();
    UPDATE PRUEBA5 SET  C1='1', C2='1', C3='1', C4='1', C5='1', C6='1', C7='1', C8='1', C9='1', C10='1', C11='1', C12='1', C13='1', C14='1', 
    C15='1', C16='1', C17='1', C18='1', C19='1', C20='1', C21='1', C22='1', C23='1', C24='1', C25='1' 
    SET @TIEMPODIFERENCIA2 = GETDAte();
    
    SET @TIEMPO3=GETDATE();
    UPDATE PRUEBA6 SET  C1='1', C2='1', C3='1', C4='1', C5='1', C6='1', C7='1', C8='1', C9='1', C10='1', C11='1', C12='1', C13='1', C14='1', 
    C15='1', C16='1', C17='1', C18='1', C19='1', C20='1', C21='1', C22='1', C23='1', C24='1', C25='1' 
    SET @TIEMPODIFERENCIA3=GETDATE();
    
    
    
    SELECT @TIEMPO, @TIEMPODIFERENCIA, @TIEMPODIFERENCIA-@TIEMPO AS EJERCICIO1, 
    	@TIEMPO2, @TIEMPODIFERENCIA2, @TIEMPODIFERENCIA2-@TIEMPO2 AS EJERCICIO2,
    	@TIEMPO3, @TIEMPODIFERENCIA3, @TIEMPODIFERENCIA3-@TIEMPO3 AS EJERCICIO3

    Observarás en la ventana de salida de mensajes, que la ejecución de las filas es la misma, pero que la tabla prueba 5 y la tabla prueba 6 que tienen el mismo contenido, que no encaja con las paginas de 64 ks que almacena por defecto el sql (de ahi viene la tontería de meter 1 caracter mas el mismo), y sin embargo y sin utilizar ningún indice teorico, leyendo los datos del monton, las lecturas logicas, fisicas pasan de 63 a 3. Y son inferiores las lecturas logicas para 25 columnas que para 2.

    Lo que podemos hacer desde la capa sql es definir una buena arquitectura, hacer que el motor cuando tenga que leer datos, tenga un camino optimo, y mantener los sistemas afinados.

    Espero no haberte soltado demasiado rollo.

    Un saludo

    Pd. No te olvides de ejcutar SET STATISTICS IO OFF

    miércoles, 18 de abril de 2018 18:17