none
Tabla con 1,248,322,792 de registros RRS feed

  • Pregunta

  • Buenos días

    Esta tabla se crea a partir de un query que hace DIFERRENTES INNER JOIN con otras tablas (no hay declaración de los constraints, ni de PK, ni de FK), cada campo utilizado en el JOIN es una llave NONCLUSTERED, se tarda casi DOS HORAS en generar la tabla de salida.

    Al intentar hacer un simple SELECT DISTINCT * FROM MyTabla, o un simple, SELECT COUNT(MyCampo) FROM MyTabla, me manda un error: (solo contiene 3 campos)

    Msg 8115, Level 16, State 2, Line 2
    Arithmetic overflow error converting expression to data type int.

    ¿El que no tenga sus CONSTRAINTS hace que mi proceso sea TAN LENTO?

    ¿Alguna recomendación para ACELERAR dicho proceso?

    Saludos


    IIslas Master Consultant SQL Server

    viernes, 2 de agosto de 2019 12:19

Todas las respuestas

  • Hola   iislas (MCP MCTS MPN DWA SQL Server)

     

    Gracias por levantar tu consulta en los foros de MSDN. Con respecto a la misma,  te comparto a continuación los siguientes enlaces donde explica el uso de CONSTRAINTS en SQL.

     

    https://docs.microsoft.com/en-us/sql/relational-databases/tables/unique-constraints-and-check-constraints?view=sql-server-2017

     https://docs.microsoft.com/en-us/sql/t-sql/statements/alter-table-table-constraint-transact-sql?view=sql-server-2017

    Gracias por usar los foros de MSDN.

     

    Pablo Rubio

     ____

     

    Por favor recuerde "Marcar como respuesta" las respuestas que hayan resuelto su problema, es una forma común de reconocer a aquellos que han ayudado, y hace que sea más fácil para los otros visitantes encontrar la solución más tarde. 

     

    Microsoft ofrece este servicio de forma gratuita, con la finalidad de ayudar a los usuarios y la ampliación de la base de datos de conocimientos relacionados con los productos y tecnologías de Microsoft.  

     

    Este contenido es proporcionado "tal cual" y no implica ninguna responsabilidad de parte de Microsoft.

    viernes, 2 de agosto de 2019 15:30
    Moderador
  • Muchas gracias Pablo

    El uso de CONSTRAINTS lo conozco, lo que no se (si alguien lo sabe), si declarando el uso de los mismos mi consulta tenga un mejor tiempo de respuesta.

    Los CONSTRAINTS cuidan el DRI

    Saludos


    IIslas Master Consultant SQL Server

    viernes, 2 de agosto de 2019 15:50
  • Primero habría que hacer el experimento de ejecutar sola la Select que trae los 1200 millones de registros, sin el Insert en la tabla de destino, para comprobar si el problema de rendimiento está en la Select o está en la grabación de esos datos en la tabla de destino.

    Un primer cálculo rápido: Si cada registro mide, por ejemplo, 4000 bytes (es una cifra grande, pero si hay un inner join de muchas tablas presumo que se están devolviendo muchos campos), entonces multiplicando eso por 1200 millones sale que estamos generando 4 Terabytes de datos. Si esos terabytes se graban sobre un array de discos que es capaz de grabar 1 Gigabyte por segundo, entonces estamos hablando de 4000 segundos, que es más de una hora. Y eso es solo para el Log, además hay que considerar la grabación de datos en el mdf, que supone otro volumen similar y presumiblemente estás grabando sobre un array de discos distinto. Asi que ya de entrada, incluso aunque la selección de datos fuera instantánea, solo con la grabación ya estamos hablando de tiempos similares a los que has mencionado. Por supuesto, todo lo anterior está basado en unas hipótesis arbitrarias en cuanto a la longitud media del registro y la velocidad de los discos. Tendrías que repetir este cálculo con los datos reales que se apliquen en tu caso.

    viernes, 2 de agosto de 2019 15:54
  • Alberto

    Como siempre, es un placer escuchar tus comentarios.

    De la combinación de tablas (INNER JOIN - LEFT JOIN), solo se obtienen 3 CAMPOS.

    Si dejo ejecutando el query en el SSME, inmediatamente me empieza a desplegar los registros.

    Si le hago INSERT a una tabla "de paso", ahi es donde se tarda las 2 horas.

    Voy a poner la tabla de salida en un disco de estado solido, como primer prueba

    Voy a colocar las tablas en cuestión y la tabla de salida IN MEMORY, ¿ves esto recomendable?

    Saludos


    IIslas Master Consultant SQL Server

    viernes, 2 de agosto de 2019 16:04
  • ¿El que no tenga sus CONSTRAINTS hace que mi proceso sea TAN LENTO?

    No exactamente. La consulta con los inner joins será lenta si faltan índices adecuados para resolverla. En la práctica, cuando hay constraints, se suelen crear índices que coinciden con los constraints. Pero son dos cosas separadas. Lo que incide en la velocidad el la presencia o ausencia de índices, no de constraints.

    Esto es bastante importante que lo estudies y lo conozcas con cierto detalle. En bases de datos pequeñas no tiene tanto impacto, pero cuando estamos hablando de miles de millones de registros, pasa a convertirse en algo importantísimo.

    viernes, 2 de agosto de 2019 16:05
  • Gracias nuevamente

    Antes, cuando esta consulta se ejecutaba, NUNCA terminaba, eran horas de proceso.

    Analizando la consulta y las tablas que intervienen en ella, me di cuenta que PRECISAMENTE le faltaban los INDICES en las columnas donde se hacían los JOIN's.

    Cree los indices y ahora si termina, pero en 1:59 minutos.

    Ya coloque las tablas (en realidad toda la base) en un disco de estado solido y analizan el consumo de recursos, veo que el 99% se lo esta llevando la MEMORIA, el disco, no representa un cuello de botella.


    IIslas Master Consultant SQL Server

    viernes, 2 de agosto de 2019 16:33
  • Bueno, la forma en la que funciona SQL Server es que según va leyendo páginas de datos desde el disco, deja esas páginas cacheadas en memoria. Esto va creciendo hasta que consume toda la memoria disponible, salvo que expresamente le pongas un límite (es conveniente que lo pongas para que deje algo de margen disponible para el sistema operativo). Si vuelve a necesitar los mismos datos, es rápido porque ya están en memoria y no tiene que acudir al disco. Si no cabe todo, va descartando las páginas menos usadas y consumiendo disco para traer las que le falten.

    Las páginas de "salida" también se dejan en memoria, además de grabarse inmediatamente en el Log. Cuando ocurre un Checkpoint, se graban desde memoria al disco de datos esas páginas nuevas.

    El resultado es que si estás grabando muchísimas páginas y leyendo muchísimas páginas, puedes dejar asfixiada o bien la memoria o bien el disco. Una de las dos cosas puede perjudicar a la otra, por ejemplo, si no hay espacio suficiente en memoria para cachear las páginas a las que se accede repetidamente, entonces se ocasionan más accesos de lo necesario al disco.

    Ojo con los datos de uso: Cuando hablas del "99%" de memoria, no da lo mismo decir que se ha consumido el 99% de la memoria (que sería normal) o que el 99% del tiempo lo pierde accediendo a memoria, cosa que casi siempre indica que está haciendo barridos de tabla sobre las páginas cacheadas y muchas veces se puede optimizar cambiando los índices.

    viernes, 2 de agosto de 2019 16:50
  • Alberto

    Lo "curioso" es que las tablas en cuestión, no tienen demasiados registros, anexo una vista con el count de cada tabla y sus registros (en ese orden que mando los count, es como se hacen los JOIN's).

    Tambien quiero comentar, que de dicha consulta solo se obtiene TRES COLUMNAS solamente.

    ¿Porque entonces hacer uso de 6 tablas?

    Porque UNA de las columnas, esta en la ultima tabla del SCREEN-SHOT y hay que "brincar" por la 3, 4 y 5a tabla para llega a ella.


    IIslas Master Consultant SQL Server

    viernes, 2 de agosto de 2019 17:18
  • Deleted
    viernes, 2 de agosto de 2019 19:28
  • Hola iislas:

    Dices al intentar un simple

    SELECT DISTINCT * FROM MyTabla,

    - Eso sobre 1.248.322.792 registros no es simple. Distinct es cualquier cosa, menos simple.

    - Viendo el numero de las filas de tus tablas, no parece que la consulta pueda generar 1.200.000.000 registros.

    No será que la consulta te esta haciendo un cross join con alguna de las tablas? y de ahí ese Distinct.

    SELECT COUNT(MyCampo) FROM MyTabla

    No debería de darte un error de ese tipo porque 1200 millones entra dentro del rango de un int. Pero puedes usar Count_Big que funciona igual, pero te devuelve un bigint.

    Si dejo ejecutando el query en el SSME, inmediatamente me empieza a desplegar los registros.

    Lo importante no es empezar, porque cuando insertas en una tabla no te va a devolver el control hasta que termines, además de que tiene que grabar datos, y no solo leerlos,.....Sin embargo el Management Studio, te va pintando las filas mientras va leyendo páginas, y puede tardar igualmente una vida en ello.

    Voy a colocar las tablas en cuestión y la tabla de salida IN MEMORY, ¿ves esto recomendable?

    Yo te diría que no.

    https://blogs.solidq.com/es/sql-server/tablas-temporales-vs-tablas-in-memory/

    sábado, 3 de agosto de 2019 6:18
  • SQL Server 2017 y es un SELECT .... INTO tabla

    IIslas Master Consultant SQL Server

    martes, 6 de agosto de 2019 19:00