none
Ayuda con optimizacion de consultas.

    Pregunta

  • Hola, tengo varias consultas con la misma estructura que deseo optimizar, por lo que entiendo se esta jalando una informacion y en una tabla temporal se traba.
    Las consultas tienen la misma estructura, en el plan de ejecucion me figura que todas tienen un RID lookup, he leido pero no entiendo muy bien que tendria que hacer, el managment me sugiere hacer un indice pero lo veo poco eficiente al implementarlo.

    -- GENERACION DE TABLA NOMINAL
    with constante (id_cita, renaes, id_persona, periodo, fichafam, ubigeo, edad, tip_edad, SEXO, ET, FI, id_profesional, Evaluacion)
    as
    (
    select id_cita, renaes, id_persona, periodo, fichafam, ubigeo, edad_reg EDAD, 
    id_tipedad_reg TIP_EDAD, id_genero SEXO, id_etnia ET, id_financiador FI, id_profesional,
    Evaluacion =
    case 
    when id_tipitem='D' and cod_item='E669' and valor_lab='IMC' then 1
    when id_tipitem='D' and cod_item='E660' and valor_lab='IMC' then 2
    when id_tipitem='D' and cod_item='Z006' and valor_lab='IMC' then 3
    when id_tipitem='D' and cod_item='E440' and valor_lab='IMC' then 4
    when id_tipitem='D' and cod_item='E43X' and valor_lab='IMC' then 5
    when id_tipitem='D' and cod_item='E344' and valor_lab='TE' then 6
    when id_tipitem='D' and cod_item='Z006' and valor_lab='TE' then 7
    when id_tipitem='D' and cod_item='E45X' and valor_lab='TE' then 8


    end from [dbo].[TRAMAHIS_DTSG] where (id_tipedad_reg='A' and edad_reg between 18 and 29) 
    )
    select id_cita, renaes, id_persona, periodo, fichafam, ubigeo, edad, tip_edad, SEXO, ET, FI, id_profesional, Evaluacion 
    into TRAMA_BASE_JOVEN_RPT_02_EVAL_NUTRIC_NOMINAL from constante where (Evaluacion between 1 and 8) ; 

    Quisiera saber que me recomiendan para poder optimizar

    Gracias!!!!!!
    martes, 15 de mayo de 2018 22:41

Respuestas

  • A que te refieres con Expresiones de filtro mas comunes en tu ambiente?

    Cuales son las consultas mas comunes y cuales sus filtros (no valores sino columnas que participan en el filtro y que tipo de filtro).  Tambien incluye GROUP BY, HAVING.

    Las columnas mas usadas en clausulas GROUP BY or ORDER BY son las mas propensas a ser usadas en un indice clustered pero usando la menor cantidad posible de estas.

    Ejemplo:

    En tablas transaccionales de un Data Warehouse, casi siempre se incluye la fecha de la transaccion y la mayoria de las consultas que se realizan sobre esta tienen la forma:

    ... where fecha >= 'yyyymmdd' and fecha < 'yyyymmdd'

    o

    ... where fecha >= 'yyyymmdd'

    o

    ... group by fecha

    Esto sugiere que tener el indice agrupado por esta columna ayudaria mucho a soportar estos queries.

    En cuanto a la fragmentacion, esto causa que se incremente el numero de paginas y que el porciento de completamiento de estas sea bajo.  Esto no es combveniente principalmente ara tablas de analisis (no OLTP).

    Aca una buena guia.

    https://www.sqlskills.com/blogs/kimberly/content/binary/indexesrightbalance-defrag.pdf?59c59e


    AMB

    Some guidelines for posting questions...

    AYÚDANOS A AYUDARTE, guía básica de consejos para formular preguntas

    • Marcado como respuesta AlexanderC1992 miércoles, 23 de mayo de 2018 22:39
    jueves, 17 de mayo de 2018 18:45

Todas las respuestas

  • Pues me parece que las únicas opciones de índice son sobre dbo.TRAMAHIS_DTSG.id_tipedad y edad_reg. Pruebe cada índice por separado y decida.

    Ah y si no es suficiente, podría insertar el resultado de la consulta dentro del WITH en una tabla temporal indizada por el campo Evaluación.  Luego procede de allí.


    Jose R. MCP
    My GIT Repositories | Mis Repositorios GIT


    • Editado webJose martes, 15 de mayo de 2018 23:59
    martes, 15 de mayo de 2018 23:58
  • Hola:

    Independientemente de los índices, y probablemente, no tenga mucha mejora.....

    Porque esa construcción compleja, cuando es más simple hacer un insert into TRAMA_BASE_JOVEN_RPT_02_EVAL_NUTRIC_NOMINAL SELECT...

    Y luego a lo mejor, le da mayor performance lo siguiente

    INSERT INTO TRAMA_BASE_JOVEN_RPT_02_EVAL_NUTRIC_NOMINAL
           SELECT id_cita,
                  renaes,
                  id_persona,
                  periodo,
                  fichafam,
                  ubigeo,
                  edad_reg,
                  id_tipedad_reg TIP_EDAD,
                  id_genero SEXO,
                  id_etnia ET,
                  id_financiador FI,
                  id_profesional,
                  CASE
                      WHEN ID_TIPITEM = 'D'
                      THEN CASE
                               WHEN cod_item = 'E669'
                                    AND valor_lab = 'IMC'
                               THEN 1
                               WHEN id_tipitem = 'D'
                                    AND cod_item = 'E660'
                                    AND valor_lab = 'IMC'
                               THEN 2
                               WHEN id_tipitem = 'D'
                                    AND cod_item = 'Z006'
                                    AND valor_lab = 'IMC'
                               THEN 3
                               WHEN id_tipitem = 'D'
                                    AND cod_item = 'E440'
                                    AND valor_lab = 'IMC'
                               THEN 4
                               WHEN id_tipitem = 'D'
                                    AND cod_item = 'E43X'
                                    AND valor_lab = 'IMC'
                               THEN 5
                               WHEN id_tipitem = 'D'
                                    AND cod_item = 'E344'
                                    AND valor_lab = 'TE'
                               THEN 6
                               WHEN id_tipitem = 'D'
                                    AND cod_item = 'Z006'
                                    AND valor_lab = 'TE'
                               THEN 7
                               WHEN id_tipitem = 'D'
                                    AND cod_item = 'E45X'
                                    AND valor_lab = 'TE'
                               THEN 8
                           END
                      ELSE 10
                  END AS EVALUACION
           FROM [dbo].[TRAMAHIS_DTSG]
           WHERE(id_tipedad_reg = 'A'
                 AND edad_reg BETWEEN 18 AND 29); 

    Me he tomado el lujo de definir como salida si id_tipitem no es igual 'd' un 10.... dado que en su case solo hay esa causistica. Supongo que un anidamiento de case, lo hará algo más efectivo, pero .....yo no lo puedo probar.

    Un saludo

    miércoles, 16 de mayo de 2018 6:27
  • Javi,

    Perdonarme por discrepar pero tu sugerencia difiere sintacticamente de la query original.  La query original solo inserta aquellas filas donde la nueva columna calculada [evaluacion] esta comprendida entre 1 y 8, pero tu sugerencia dejaria tambien insertar filas cuyo valor de  esa columna este fuera de los limites.

    Es ese caso habria que copiar esa expresion CASE en la clausula WHERE para limitar las filas.  Como vez, la sentencia se tornaria un poco ilegible.

    selec ..., CASE END AS evaluacion
    from ...
    where ... and CASE END between 1 and 8;

    Aun asi, el desempenio no cambiaria ya que la expresion CASE en este caso seria similar a multiples expresiones logicas unidas por OR.

    select ...
    from ...
    where ... and (
    (id_tipitem = 'D' and cod_item = 'E669' and valor_lab = 'IMC')
    or
    (id_tipitem = 'D' and cod_item = 'E660' and valor_lab = 'IMC')
    or
    ...
    );


    AMB

    Some guidelines for posting questions...

    AYÚDANOS A AYUDARTE, guía básica de consejos para formular preguntas



    miércoles, 16 de mayo de 2018 12:15
  • Sin saber mucho de los planes de ejecucion relacionados con esa consulta y ambiente, pareceria que se necesita recorrer la tabla o indice por la condicion (id_tipedad_reg = 'A' and edad_reg between 18 and 29), de las filas resultantes calcular la nueva columna [evaluacion] y despues filtrar aquellas donde el nuevo valor este entre 1 y 8.

    Si te encuentras usando esa expresion case frecuentemente, una posible sugerencia seria que aniadas una columna calculada a la tabla y uno que otro indice para soportar esa expresion de filtro.

    Por ejemplo, podrias aniadir un indice filtrado por esa columna calculada usando como llave las columnas (id_tipedad_reg, edad_reg) e incluyendo (id_tipitem, cod_item, valor_lab, ...).


    AMB

    Some guidelines for posting questions...

    AYÚDANOS A AYUDARTE, guía básica de consejos para formular preguntas


    miércoles, 16 de mayo de 2018 12:20
  • Pues me parece que las únicas opciones de índice son sobre dbo.TRAMAHIS_DTSG.id_tipedad y edad_reg. Pruebe cada índice por separado y decida.

    Ah y si no es suficiente, podría insertar el resultado de la consulta dentro del WITH en una tabla temporal indizada por el campo Evaluación.  Luego procede de allí.


    Jose R. MCP


    Ya he creado los indices que me comentas pero la mejora no es sustancial, con respecto a insertar el resultado dentro del with no estoy seguro que tanto podria agilizar la consulta. Voy a intentarlo, gracias Jose!
    miércoles, 16 de mayo de 2018 13:10
  • Hola:

    Independientemente de los índices, y probablemente, no tenga mucha mejora.....

    Porque esa construcción compleja, cuando es más simple hacer un insert into TRAMA_BASE_JOVEN_RPT_02_EVAL_NUTRIC_NOMINAL SELECT...

    Y luego a lo mejor, le da mayor performance lo siguiente

    INSERT INTO TRAMA_BASE_JOVEN_RPT_02_EVAL_NUTRIC_NOMINAL
           SELECT id_cita,
                  renaes,
                  id_persona,
                  periodo,
                  fichafam,
                  ubigeo,
                  edad_reg,
                  id_tipedad_reg TIP_EDAD,
                  id_genero SEXO,
                  id_etnia ET,
                  id_financiador FI,
                  id_profesional,
                  CASE
                      WHEN ID_TIPITEM = 'D'
                      THEN CASE
                               WHEN cod_item = 'E669'
                                    AND valor_lab = 'IMC'
                               THEN 1
                               WHEN id_tipitem = 'D'
                                    AND cod_item = 'E660'
                                    AND valor_lab = 'IMC'
                               THEN 2
                               WHEN id_tipitem = 'D'
                                    AND cod_item = 'Z006'
                                    AND valor_lab = 'IMC'
                               THEN 3
                               WHEN id_tipitem = 'D'
                                    AND cod_item = 'E440'
                                    AND valor_lab = 'IMC'
                               THEN 4
                               WHEN id_tipitem = 'D'
                                    AND cod_item = 'E43X'
                                    AND valor_lab = 'IMC'
                               THEN 5
                               WHEN id_tipitem = 'D'
                                    AND cod_item = 'E344'
                                    AND valor_lab = 'TE'
                               THEN 6
                               WHEN id_tipitem = 'D'
                                    AND cod_item = 'Z006'
                                    AND valor_lab = 'TE'
                               THEN 7
                               WHEN id_tipitem = 'D'
                                    AND cod_item = 'E45X'
                                    AND valor_lab = 'TE'
                               THEN 8
                           END
                      ELSE 10
                  END AS EVALUACION
           FROM [dbo].[TRAMAHIS_DTSG]
           WHERE(id_tipedad_reg = 'A'
                 AND edad_reg BETWEEN 18 AND 29); 

    Me he tomado el lujo de definir como salida si id_tipitem no es igual 'd' un 10.... dado que en su case solo hay esa causistica. Supongo que un anidamiento de case, lo hará algo más efectivo, pero .....yo no lo puedo probar.

    Un saludo

    Gracias Javi por tomarte la molestia de realizar todo ese query, aunque como dice Hunchback, me parece que cambia la logica de mi query, he estado probando modificar la consulta de varias formas pero no ubico como hacerlo.

    miércoles, 16 de mayo de 2018 13:13
  • Sin saber mucho de los planes de ejecucion relacionados con esa consulta y ambiente, pareceria que se necesita recorrer la tabla o indice por la condicion (id_tipedad_reg = 'A' and edad_reg between 18 and 29), de las filas resultantes calcular la nueva columna [evaluacion] y despues filtrar aquellas donde el nuevo valor este entre 1 y 8.

    Si te encuentras usando esa expresion case frecuentemente, una posible sugerencia seria que aniadas una columna calculada a la tabla y uno que otro indice para soportar esa expresion de filtro.

    Por ejemplo, podrias aniadir un indice filtrado por esa columna calculada usando como llave las columnas (id_tipedad_reg, edad_reg) e incluyendo (id_tipitem, cod_item, valor_lab, ...).


    AMB


    Hunchback, en el plan de ejecución efectivamente, lee todo el indice y lo filtra pero a la par tengo un RID lookup que al parecer es donde copia toda la data en la tabla consolidada.

    Tengo un año como analista de aplicaciones y recién me están dando labores de tuneo de querys y estoy un poco perdido por que nunca vi esto ni siquiera en el instituto, ya estoy leyendo bien los planes de ejecución y he añadido indices que han mejorado sustancialmente pero sigo afinando.

    Muchas Gracias a todos por su ayuda, sigo a la espera de alguna otra opinión.

    miércoles, 16 de mayo de 2018 13:20
  • Hola Hunchback:

    Ojala, todo el mundo discrepará, ya que si todo el mundo estuviese de acuerdo, todavía tendría mi Spectrum 16 kb y probablemente estaría programando en QBasic. :)

    Se me pasó el case del where, pero piensa que según iba el post, y con lo de que no mejora añadiendo los dos indices, de la consulta poco se podía rascar.

    Desde mi punto de vista, (teniendo en cuenta que dice que los indices, no le aportan, de lo cual entiendo que el plan de ejecución esta leyendo casi todo y siendo ineficaz, porque sino no habría post), la única posibilidad era hacerle que lea menos, o mejor dicho, que el where afináse y no leyese la tabla entera. Para que obtuviese diferentes lecturas en función de lo que le llegase. Leí la consulta me hice mi idea en la cabeza, pense en un procedure, que recibiría parametros, puesto que sino no, estaría aquí, y me quede solo con lo que mi cerebro de mañana, me dió.

    Pensando en un varias consultas iguales, pero diferentes dentro de IF en un sp.

    Saludos

    miércoles, 16 de mayo de 2018 15:37
  • Hola Hunchback:

    Ojala, todo el mundo discrepará, ya que si todo el mundo estuviese de acuerdo, todavía tendría mi Spectrum 16 kb y probablemente estaría programando en QBasic. :)

    Se me pasó el case del where, pero piensa que según iba el post, y con lo de que no mejora añadiendo los dos indices, de la consulta poco se podía rascar.

    Desde mi punto de vista, (teniendo en cuenta que dice que los indices, no le aportan, de lo cual entiendo que el plan de ejecución esta leyendo casi todo y siendo ineficaz, porque sino no habría post), la única posibilidad era hacerle que lea menos, o mejor dicho, que el where afináse y no leyese la tabla entera. Para que obtuviese diferentes lecturas en función de lo que le llegase. Leí la consulta me hice mi idea en la cabeza, pense en un procedure, que recibiría parametros, puesto que sino no, estaría aquí, y me quede solo con lo que mi cerebro de mañana, me dió.

    Pensando en un varias consultas iguales, pero diferentes dentro de IF en un sp.

    Saludos

    Javi me diste una gran idea, en tu mejora del where y del when, logre optimizar un poco la consulta haciendo 2 when en el id_tipitem = 'D', al repetir esta búsqueda demoraba mucho, logro reducir 30 segundos, el plan de ejecución no cambia pero mejora la cosa (TODO ESTO CON EL CLEANBUFFER). También he pensado hacer una IF ELSE, según he leído es mucho mas optimo.

    Yo sigo probando y agradezco a todos con su ayuda, si se les ocurre alguna idea o algo que pueda probar no duden en hacérmelo saber, que leeré y lo probare. Muchas Gracias!

    miércoles, 16 de mayo de 2018 16:34
  • Me alegro mucho.....
    miércoles, 16 de mayo de 2018 18:20
  • Me alegro mucho.....
    Que ánimos hombre jaja
    miércoles, 16 de mayo de 2018 19:40
  • Alexander,

    Para nosotros es dificil poder dar alguna sugerencia con la poca informacion que nos proporcionas sobre tu tabla.

    - Estructura de la tabla (tipos de data, restricciones pk, unicidad y fk, etc.)

    - Al menos cuantas filas tiene

    - Indices existentes

    - Expresiones de filtro mas comunes en tu ambiente

    - Columna(s) que se puedan usar para crear un indice agrupado, ya que esa tabla no cuenta con uno

    - Grado de fragmentacion actual de la tabla (heap)

    Como mencione antes, pudieras adicionar una columna calculada a tu tabla, crear un indice cubierto.

    Ejemplo:

    CREATE TABLE dbo.TRAMAHIS_DTSG (
    id_tipedad_reg int NOT NULL, 
    edad_reg int NOT NULL,
    id_cita int NOT NULL, 
    renaes int NOT NULL, 
    id_persona int NOT NULL, 
    periodo int NOT NULL, 
    fichafam int NOT NULL, 
    ubigeo int NOT NULL, 
    id_genero int NOT NULL, 
    id_etnia int NOT NULL, 
    id_financiador int NOT NULL, 
    id_profesional int NOT NULL, 
    id_tipitem varchar(10) NOT NULL, 
    cod_item varchar(10) NOT NULL, 
    valor_lab varchar(10) NOT NULL,
    evaluacion AS
    	CAST( 
    	CASE 
    	WHEN id_tipitem='D' AND cod_item='E669' AND valor_lab='IMC' THEN 1
    	WHEN id_tipitem='D' AND cod_item='E660' AND valor_lab='IMC' THEN 2
    	WHEN id_tipitem='D' AND cod_item='Z006' AND valor_lab='IMC' THEN 3
    	WHEN id_tipitem='D' AND cod_item='E440' AND valor_lab='IMC' THEN 4
    	WHEN id_tipitem='D' AND cod_item='E43X' AND valor_lab='IMC' THEN 5
    	WHEN id_tipitem='D' AND cod_item='E344' AND valor_lab='TE' THEN 6
    	WHEN id_tipitem='D' AND cod_item='Z006' AND valor_lab='TE' THEN 7
    	WHEN id_tipitem='D' AND cod_item='E45X' AND valor_lab='TE' THEN 8
    	ELSE -1
    	END AS smallint) PERSISTED
    )
    GO
    CREATE NONCLUSTERED INDEX ix_nc_tramahist_dtsg_ter_er ON dbo.TRAMAHIS_DTSG (id_tipedad_reg, edad_reg, evaluacion)
    INCLUDE (
    	id_cita, 
    	renaes, 
    	id_persona, 
    	periodo, 
    	fichafam, 
    	ubigeo, 
    	id_genero, 
    	id_etnia, 
    	id_financiador, 
    	id_profesional
    	)
    GO
    SELECT
    	id_cita, renaes, id_persona, periodo, fichafam, ubigeo, edad_reg EDAD, 
    	id_tipedad_reg TIP_EDAD, id_genero SEXO, id_etnia ET, id_financiador FI, id_profesional, 
    	evaluacion
    FROM 
    	[dbo].[TRAMAHIS_DTSG] 
    WHERE 
    	id_tipedad_reg ='A' 
    	AND edad_reg BETWEEN 18 and 29
    	AND evaluacion BETWEEN 1 AND 8;
    GO

    En el plan encontraras un index seek (mas scan por tener predicado residual).

    Claro esta que el plan de ejecucion podria cambiar de acuerdo a las estadisticas que tengas en tu ambiente.

    Siempre que hagas una pregunta como esta, ten en cuenta que mientras mas informacion proporciones mejor sera el chance de que te puedan ayudar con recomendaciones basados en hechos.

    Ayudanos para poder ayudarte.


    AMB

    Some guidelines for posting questions...

    AYÚDANOS A AYUDARTE, guía básica de consejos para formular preguntas


    jueves, 17 de mayo de 2018 12:24
  • Hunchback, como comentaba soy muy nuevo en esto. Yo he trabajado realizando consultas y reportes simples. En este proyecto soy nuevo y esta base de datos tampoco la conozco. He revisado y esta tabla es para DWH, todas los procedimientos son creados para un estudio estadístico de la data transaccional.

    Respondiendo un poco a tu pregunta, la estructura es esta

    id_ups varchar(6)
    id_profesion varchar(2)
    clasificacion int
    fgdig int
    id_persona int
    id_establecimiento int
    rownum int
    id_corr_diag int
    cod_item varchar(10)
    id_tipitem varchar(2)
    fg_tipo varchar(2)
    valor_lab varchar(6)
    id_corr_lab int
    id_gruporiesgo int
    id_comorbilidad int
    id_colegio varchar(2)
    fg_linea int
    pc decimal(6, 2)
    perimetro_abdominal varchar(6)
    peso decimal(10, 2)
    talla decimal(6, 2)
    hb varchar(6)
    fecha_exfisico datetime
    FechaRegistro varchar(8)
    etapa int
    cod_item_f char(3)

    No tiene pk ni fk, no es la transaccional y los indices son estos


    CREATE NONCLUSTERED INDEX [idx_nc_dtsg_NIÑO_RPT_12_01] ON [dbo].[TRAMAHIS_DTSG]
    (
    [cod_item] ASC
    )
    INCLUDE ( [edad_reg],
    [id_tipedad_reg],
    [id_cita],
    [valor_lab])


    CREATE NONCLUSTERED INDEX [idx_nc_dtsg_NIÑO_RPT_12] ON [dbo].[TRAMAHIS_DTSG]
    (
    [cod_item] ASC
    )
    INCLUDE ( [id_cita],
    [id_tipitem],
    [valor_lab]) 


    CREATE NONCLUSTERED INDEX [idx_nc_dtsg_fg_tipo_cod_item_f] ON [dbo].[TRAMAHIS_DTSG]
    (
    [fg_tipo] ASC,
    [cod_item_f] ASC
    )

    CREATE NONCLUSTERED INDEX [idx_nc_dtsg_cod_item-id_cita] ON [dbo].[TRAMAHIS_DTSG]
    (
    [cod_item] ASC
    )
    INCLUDE ( [id_cita]) 

    A que te refieres con Expresiones de filtro mas comunes en tu ambiente? Lo puedo averiguar pero como te comente no conozco esta base de datos aunque no entendi eso de las expresiones de filtro, disculpame pero como comente soy nuevo en esto.

    Como puedo determinar las columnas que puedo usar para crear un indice agrupado?

    Grado de fragmentacion actual de la tabla (heap), aqui si estoy perdido, estuve leyendo un par de consultas y me figura lo siguiente, por favor corrigeme si no esta bien

    avg_fragmentation_in_percent = 0.676084967984551

    fragment_count = 1670

    page_count = 1967782

    En realidad que añada un campo a la tabla es muy complicado debido a que tengo que optimizar de otras maneras hasta que me den la confianza de poder generar nuevos campos. Estoy buscando ir mejorando y que vean mi trabajo y el dba me de esa confianza.

    Hunchback gracias por darte el tiempo de ayudarme.

    Saludos

    jueves, 17 de mayo de 2018 16:06
  • A que te refieres con Expresiones de filtro mas comunes en tu ambiente?

    Cuales son las consultas mas comunes y cuales sus filtros (no valores sino columnas que participan en el filtro y que tipo de filtro).  Tambien incluye GROUP BY, HAVING.

    Las columnas mas usadas en clausulas GROUP BY or ORDER BY son las mas propensas a ser usadas en un indice clustered pero usando la menor cantidad posible de estas.

    Ejemplo:

    En tablas transaccionales de un Data Warehouse, casi siempre se incluye la fecha de la transaccion y la mayoria de las consultas que se realizan sobre esta tienen la forma:

    ... where fecha >= 'yyyymmdd' and fecha < 'yyyymmdd'

    o

    ... where fecha >= 'yyyymmdd'

    o

    ... group by fecha

    Esto sugiere que tener el indice agrupado por esta columna ayudaria mucho a soportar estos queries.

    En cuanto a la fragmentacion, esto causa que se incremente el numero de paginas y que el porciento de completamiento de estas sea bajo.  Esto no es combveniente principalmente ara tablas de analisis (no OLTP).

    Aca una buena guia.

    https://www.sqlskills.com/blogs/kimberly/content/binary/indexesrightbalance-defrag.pdf?59c59e


    AMB

    Some guidelines for posting questions...

    AYÚDANOS A AYUDARTE, guía básica de consejos para formular preguntas

    • Marcado como respuesta AlexanderC1992 miércoles, 23 de mayo de 2018 22:39
    jueves, 17 de mayo de 2018 18:45