Visual Basic.NET - Mejorar Consulta mysql desde Vb.net

 
Vista:
sin imagen de perfil

Mejorar Consulta mysql desde Vb.net

Publicado por Alfredo (9 intervenciones) el 03/08/2021 05:14:22
Amigos,
tengo una consulta desde VB. net para listar todo un mayor contable.. el cual contiene ::: columna ..datos ..../ debe/ haber/ saldo/.. pero informo un /saldo anterior/ que es calculado en una sub-consulta .. mi codigo es demasiado lento.. se demora entre 40 y 50 segundos y aveces más de 60 .. interrumpiendo el programa..
los datos son llevados al Crystal Report el cual me fabrica el formato del Mayor.
cómo podría mejorar esta consulta..???

Sql = "SELECT *, mov_debe, mov_haber, " & _
"(mov_debe - mov_haber) as saldo," & _
"(select sum(mov_debe - mov_haber) as Anterior from Movimiento_contable where org_rut='" & rut & "' and cen_codigo= C.cen_codigo and mov_fecha between '" & Format(Date0, "yyyy-MM-dd") & "' and '" & Format(Date1.Value.AddDays(-1), "yyyy-MM-dd") & "') as saldo_Anterior " & _
"FROM movimiento_contable INNER JOIN empresa on (empresa.org_rut = movimiento_contable.org_rut) " & _
" INNER JOIN centro_costo C on (C.cen_codigo = movimiento_contable.cen_codigo) and (C.org_rut = movimiento_contable.org_rut)" & _
" where movimiento_contable.ORG_RUT= '" & rut & "' and mov_fecha Between '" & Format(Date1.Value, "yyyy-MM-dd") & "' " & _
"AND '" & Format(Date2.Value, "yyyy-MM-dd") & "' order by mov_fecha,cen_codigo asc"

mi dato esperado es

datos..../ debe / haber / saldoDeLaLinea / saldoAnteriorDeLaCuenta-

gracias
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder
Imágen de perfil de Phil Rob
Val: 3.353
Oro
Ha mantenido su posición en Visual Basic.NET (en relación al último mes)
Gráfica de Visual Basic.NET

Mejorar Consulta mysql desde Vb.net

Publicado por Phil Rob (1242 intervenciones) el 03/08/2021 08:09:00
Hola,

Comprendo la contabilidad y las nociones Debe/Haber. También comprendo "datos..../ debe / haber / saldoDeLaLinea / saldoAnteriorDeLaCuenta", comprendo pero no es suficiente.

Ya he te propongo de enviar una parte o un ejemplo de la tabla Movimiento_contable, y un ejemplo de los resultados que quieras con estos datos.
Este nos permitirá de mejor comprender tu problema y podemos intentar varias soluciones con este tabla.
Sin este, es muy difícil de trabajar una consulta SQL complexa.
La tabla que envías puede tener datos ficticias, solamente coherentes.
Puedes enviar con correo prívate si los datos están confidenciales, el sito permite este correo cuando “Click” el nombre del correspondiente en la cabecera del mensaje.

Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
Imágen de perfil de Phil Rob
Val: 3.353
Oro
Ha mantenido su posición en Visual Basic.NET (en relación al último mes)
Gráfica de Visual Basic.NET

Mejorar Consulta mysql desde Vb.net

Publicado por Phil Rob (1242 intervenciones) el 03/08/2021 09:00:48
Continuación ...

Te propongo de llenar con ± 20 lineas, la hoja DebeHaber.XLS que he adjuntado a este mensaje.
Las columnas utilizadas en tu consulta están importantes. Las columnas SoldoAnterior y Soldo están para mostrar los resultados que quieras.

Con esta hoja XLS, puedo hacer una tabla en un sistema de DB y testar las consultas.

...
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil

Mejorar Consulta mysql desde Vb.net

Publicado por Alfredo (9 intervenciones) el 03/08/2021 16:02:09
hola amigo,
adjunto planilla con algunos resultados que he sacado, pero se pega la consulta..
serán muchos datos?? con solo una cuenta funciona re-bien.. pero cuando listar todos las cuentas del año se me pega..
son alrededor de 1400 registros para el informe que ordena Crystal Report.

muchas gracias por tu tiempo..
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
Imágen de perfil de Phil Rob
Val: 3.353
Oro
Ha mantenido su posición en Visual Basic.NET (en relación al último mes)
Gráfica de Visual Basic.NET

Mejorar Consulta mysql desde Vb.net

Publicado por Phil Rob (1242 intervenciones) el 03/08/2021 16:39:56
Muy bien tu hoja XLS.

Veo que el Saldo concierne la línea actual. Siempre es mov_debe – mov_haber.
Pero no cambia el saldo_Anterior. Como calculas este valor: del 1 de enero hasta el último día del mes anterior? En tu ejemplo, del 1/1/2021 hasta 30/6/2021?
Esta permitido añadir una tabla con los saldos anterior con : cen_codigo / saldo_anterior / total_saldo_actual? Porque no es bien recalcular saldo_anterior para cada movimiento.

Te envio estas preguntas sin haber comenzado a reflexionar. Espero tus repuestas y pensaré luego.

...
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil

Mejorar Consulta mysql desde Vb.net

Publicado por Alfredo (9 intervenciones) el 03/08/2021 17:25:02
asi es,, "saldo" es solo linea actual mov_debe - mov_haber.-
"saldo anterior" es una subconsulta que obtiene el conteo la misma cuenta desde la fecha anterior( 01/01/2021 al30/06/2021),
este ultimo dato se repite en todas las lineas..
luego en el crystal report hago una formula que suma el saldo con el saldo anterior...

en este ultimo paso tengo una sobre generacion de recurso , ya que cada vez que se imprime un linea consulta el saldo anterior de cada fila según el cen_codigo.
favor habrá otra forma de imprimir lo mismo pero sin gastar tanto recurso..y que funcione?
gracias
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
Imágen de perfil de Phil Rob
Val: 3.353
Oro
Ha mantenido su posición en Visual Basic.NET (en relación al último mes)
Gráfica de Visual Basic.NET

Mejorar Consulta mysql desde Vb.net

Publicado por Phil Rob (1242 intervenciones) el 03/08/2021 17:32:49
"favor habrá otra forma de imprimir lo mismo pero sin gastar tanto recurso..y que funcione?"

Este es a este que voy reflexionar ...
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil

Mejorar Consulta mysql desde Vb.net

Publicado por Alfredo (9 intervenciones) el 03/08/2021 17:56:15
grande Master!!!! Espero su consejo!.

gracias por tu tiempo!!!
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
Imágen de perfil de Phil Rob
Val: 3.353
Oro
Ha mantenido su posición en Visual Basic.NET (en relación al último mes)
Gráfica de Visual Basic.NET

Mejorar Consulta mysql desde Vb.net

Publicado por Phil Rob (1242 intervenciones) el 04/08/2021 10:51:42
Hola Alfredo,

Tengo una consulta que da los mismos resultados que en tu hoja XLS. Excepto que estan ordenados por mov_fecha y cen_codigo. En la hoja XLS, están solamente ordenados por mov_fecha. En este caso, tienes las varias líneas de mismas fecha y mismo código que no están siguientes. Quizá será posible de quitar este clasificación con cen_codigo en los resultados. Pero hablo de detalles …

El problema es que no he encontrado consulta más simple. Pienso que mi consulta durara como la tuya.

Comprendo que llenar un CristalReport con los resultados de este consulta. Supongo que estos resultados están cargados en un DataTable y que este DataTable es unido con el report.
Si es bien este caso, mejor sería de hacer 2 DataTable.

DataTable SaldoAnterior llenado con la consulta :

SELECT cen_codigo, SUM(mov_debe - mov_haber) AS SaldoAnterior
FROM Movimiento_contable
WHERE Format(mov_fecha, "yyyymmdd") between "20210101" AND "20210630"
GROUP BY cen_codigo;

Datatable SaldoActual llenado con la consulta :

SELECT cen_codigo, cen_nombre, mov_fecha, mov_debe, mov_haber, Sum(mov_debe-mov_haber) AS Saldo
FROM Movimiento_contable
WHERE (((Format([mov_fecha],"yyyymmdd")) Between "20210701" And "20210731"))
GROUP BY Movimiento_contable.cen_codigo, Movimiento_contable.cen_nombre, Movimiento_contable.mov_fecha, mov_debe, mov_haber
ORDER BY mov_fecha

Tras estas consultas, los campos del CristalReport están llenados con la combinación de los 2 Datatable (no sé bien CristalReport).

Con mi consulta y la tuya, la consulta SaldoAnterior es recalculada para cada línea de SaldoActual. Si haces 2 DataTable, la consulta SaldoAnterior es ejecutada una vez.

No sé cuál sistema de DB utilizas. He probado con Access2013. Para poder calcular el saldo anterior, he agregada las líneas con el saldo en 30/06/2021. Otros datos están cuales de tu hoja XLS.
Adjunto mi DB con mis pruebas para ti probar si lo quieras. Encontraras las consultas SaldoActual, SaldoAnterior y Resultados.

Espero que mis comentarios te ayudaran …
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
Imágen de perfil de Phil Rob
Val: 3.353
Oro
Ha mantenido su posición en Visual Basic.NET (en relación al último mes)
Gráfica de Visual Basic.NET

Mejorar Consulta mysql desde Vb.net

Publicado por Phil Rob (1242 intervenciones) el 05/08/2021 14:52:39
Hola Alfredo,

Todavía trabajar con tu problema pero no encuentro una buena solución con una sola consulta.

Quizá puedes preguntar la simplificación de la consulta en el foro SQL :

https://www.lawebdelprogramador.com/foros/SQL/index1.html

Después, sera todavía el tiempo para ajustar la programación con VB.

Lo siento de no te dar mejor resultado ...
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
Imágen de perfil de melqui
Val: 643
Bronce
Ha mantenido su posición en Visual Basic.NET (en relación al último mes)
Gráfica de Visual Basic.NET

Mejorar Consulta mysql desde Vb.net

Publicado por melqui (235 intervenciones) el 06/08/2021 19:20:00
hola alfredo,
sacame una duda, tu trabajas con indice en tu consulta?

en su mayoria las soluciones para trabajar en base de datos principalmente flexibilizar la lentitud es por causa de que no se aplican los indices
esto genera lentitud, por esta razon tanto en mysql y mariadb facilita indexar
esto hace que el retorno de tu consulta sea mas rapido.
a una simple vista en tu codigo, veo que estas trabajando con filtros muy complexo esto genera una grande decmanda de recursos.
creo que la mejor forma de agilizar tu codigo es creando una procedure. y otimizar las consultas.

vea los tipo de indice que puedes usar.
Screenshot_7

han una cosa importante tambien que te puede ayudar. cuando haces una consulta generalmente esto hacer una carga tremenda en la memoria. dependiendo de como lo estas trabajando.
principalmente en relatorios. toda vez que usas datatable, dataset. esto tipos de cargas no son liberados rapidos de la memoria. esto lo tienes que liberar. asi cuando ejecutes una nueva carga se flexibilize tu consulta.
para liberar despues de cargar tus datos simples haga un dispose o trabaje con los using.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil

Mejorar Consulta mysql desde Vb.net

Publicado por Alfredo (9 intervenciones) el 06/08/2021 23:31:33
hola amigos..
realizaré la prueba con dos DataTable, quizás si las fusiono desde Crystal report podré mejorar la agilidad..
y después estudiaré como usar el dispose o el using.

les cuento como me va..

gracias Amigos.. todas la sugerentes las tomo para mi aprendizaje..
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
Imágen de perfil de Phil Rob
Val: 3.353
Oro
Ha mantenido su posición en Visual Basic.NET (en relación al último mes)
Gráfica de Visual Basic.NET

Mejorar Consulta mysql desde Vb.net

Publicado por Phil Rob (1242 intervenciones) el 08/08/2021 16:51:24
Hola Alfredo,

Muy bien …

Pero he continuado a reflexionar a tu problema, al problema de rapidez del tratamiento.

He escrito una consulta que dar todos resultados: Saldo del movimiento (por línea), Saldo del periodo en curso y Saldo del periodo anterior.
Esta consulta lee 3 veces la tabla, este es mucho menos que 1 vez por cada cen_mov encontrado. En VB, puedes utilizar una DataTable y seleccionar el Solda que quieres con el valor de tipo_mov.
El valor de tipo_mov es su valor normal en la contabilidad para cada Saldo del movimiento. Para el Periodo anterior, esto valor es "Periodo anterior" y para el Periodo en curso, esto valor es "Periodo en curso". Puedes cambiar estos valores determinantes como te gusta. Para ver el mismo ordenamiento que cual de mi consulta, este bien de poner estos valores más grande que los valores de los tipos de la contabilidad y haber tipo periodo actual más grande que el tipo periodo anterior.

Me permito un comentario. En la contabilidad, escribimos nunca un valor Debe y un valor Haber en la misma línea. La más simple escritura de contabilidad contiene 2 líneas: una para un Debe y una para un Haber, a menudo este es varias líneas que están escritas, con un total debe igual al total Haber. Si todos tus datos están escritos como este, entonces la columna Saldo del movimiento no debería ser necesario: es suficiente de mirar las columnas Debe y Haber para saber.
Pero quizá tus datos no vienen de una contabilidad oficial…

Adjunto mi DB Access para ti probar.

Este es la consulta:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
SELECT cen_codigo, cen_nombre, mov_fecha, mov_tipo, mov_debe, mov_haber,  Null AS SaldoPeriodAnterior, Null AS SaldoPeriodActual, Sum(mov_debe-mov_haber) AS SaldoEsteMov
FROM Movimiento_contable
WHERE (((Format([mov_fecha],"yyyymmdd")) Between "20210701" And "20210731"))
GROUP BY cen_codigo, cen_nombre,  mov_fecha, mov_tipo, mov_debe, mov_haber, Null, Null
UNION
SELECT cen_codigo, cen_nombre,  Null As mov_fecha, "Periodo en curso" As mov_tipo, Null As Debe , Null As Haber, Null As SaldoPeriodAnterior , SUM(mov_debe - mov_haber) AS SaldoPeriodActual, Null As SaldoEsteMov
FROM Movimiento_contable
WHERE Format(mov_fecha, "yyyymmdd") between "20210701" AND "20210731"
GROUP BY cen_codigo, cen_nombre, Null,  Null, Null, Null
UNION
SELECT cen_codigo, cen_nombre, Null As mov_fecha, "Periodo anterior" As mov_tipo, Null As Debe , Null As Haber , SUM(mov_debe - mov_haber) AS SaldoPeriodAnterior, Null AS SaldoPeriodActual, Null As SaldoEsteMov
FROM Movimiento_contable
WHERE Format(mov_fecha, "yyyymmdd") between "20210101" AND "20210630"
GROUP BY  cen_codigo, cen_nombre, Null,  Null, Null, Null;

Este es el resultado:
Alfredo

Espero que este te ayudará….
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar