Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   SQL (https://www.clubdelphi.com/foros/forumdisplay.php?f=6)
-   -   Como optimizar sql (https://www.clubdelphi.com/foros/showthread.php?t=93345)

homy988 11-08-2018 02:46:33

Como optimizar sql
 
buenas tardes:

como puedo optimizar esta consulta.

se tarda muchisimo ya que ocupo demaciados registros.

Código Delphi [-]
 
      qry.sql.add('SELECT  MAX(campo1) AS a,');
      qry.sql.add('(SELECT MAX(campo2) AS b');
      qry.sql.add('FROM tabla1');
      qry.sql.add('WHERE campo3=1 AND campo4= 'texto' AND campo2<6584651)');
      qry.sql.add('FROM CFDI');
      qry.sql.add('WHERE campo3=1 AND campo4= 'texto' AND campo2<:6584651');

mamcx 11-08-2018 03:00:05

Que exactamente es

Cita:

se tarda muchisimo (cuanto?) ya que ocupo demaciados registros (como asi?)
Para optimizar la consulta, analiza el query plan que te de la BD.

Casimiro Notevi 11-08-2018 12:25:34

Cita:

Empezado por homy988 (Mensaje 528022)
como puedo optimizar esta consulta.
se tarda muchisimo ya que ocupo demaciados registros.

Esto es como si vas al médico y le dices:

Doctor, ¿qué puedo hacer para que a mi hijo no le duela?

Ahora, imagina qué te contestará el doctor.
Pues lo mismo.

homy988 14-08-2018 21:40:10

Gracias por sus tips para plantear el tema:

resulta que tengo una tablaDB similar a esta:


Dato1 dato2 dato3 dato4
1 59 dsfg sdfg
2 60 sdfg sdfg
3 61 dsfg sdfg
4 62 dsfg sdfg



8 66 sdfg sdfg
9 67 dsfg sdfg
10 68 dsfg sdfg
11 69 sdfg sdfg


y obtengo el registro de en medio:

Dato1 dato2 dato3 dato4
" " 64 dsfg sdfg

sin el Dato1.


normalmente lo que haría alguien normal es recorrer tupla por tupla, pero yo en lugar de eso,
uso el dato2, y busco el máximo menor en la BD, ademas, busco el máximo de dato1.

de este modo, obtengo los datos:

Dato1 dato2
4 62

después le resto el dato2 actual con el dato2 de la BD y obtengo la cantidad de espacios entre ellos,
así pues, uso el dato1 de la BD y le sumo el resultado de la resta,

para obtener el numero 6 que debo insertar en la BD con los datos completos.
asi mi registro completo queda de la siguiente manera:

Dato1 dato2 dato3 dato4
6 64 dsfg sdfg


y mi tabla queda un poco mas completa:

Dato1 dato2 dato3 dato4
1 59 dsfg sdfg
2 60 sdfg sdfg
3 61 dsfg sdfg
4 62 dsfg sdfg

6 64 dsfg sdfg

8 66 sdfg sdfg
9 67 dsfg sdfg
10 68 dsfg sdfg
11 69 sdfg sdfg


lo que quiero es optimizar la consulta, ya que tengo mas de 600 mil registros, y se tarda un poco esta consulta.

una disculpa por no colocar todo en tabla.

Casimiro Notevi 14-08-2018 21:43:34

No lo entiendo.
De dónde sacas esto, si no existe:

" " 64 dsfg sdfg

ecfisa 14-08-2018 22:59:13

Hola.
Cita:

Empezado por homy988 (Mensaje 528022)
buenas tardes:

como puedo optimizar esta consulta.

se tarda muchisimo ya que ocupo demaciados registros.

Código Delphi [-]
 
      qry.sql.add('SELECT  MAX(campo1) AS a,');
      qry.sql.add('(SELECT MAX(campo2) AS b');
      qry.sql.add('FROM tabla1');
      qry.sql.add('WHERE campo3=1 AND campo4= 'texto' AND campo2<6584651)');
      qry.sql.add('FROM CFDI');
      qry.sql.add('WHERE campo3=1 AND campo4= 'texto' AND campo2<:6584651');

Extrayendo el código SQL queda:
Código SQL [-]
SELECT  MAX(campo1) AS a,
SELECT MAX(campo2) AS b
FROM tabla1
WHERE campo3 = 1 AND campo4 = 'texto' AND campo2 <6584651 
FROM CFDI
WHERE campo3=1 AND campo4= 'texto' AND campo2<:6584651
¿ Y no te arroja ningún error así como está ?

Saludos :)

homy988 15-08-2018 01:16:20

Cita:

Empezado por Casimiro Notevi (Mensaje 528064)
No lo entiendo.
De dónde sacas esto, si no existe:

" " 64 dsfg sdfg

Mira, lo que pasa es no es que no se tenga, lo que pasa es que en su momento no se actualizo, por errores de conexión, sin embargo los datos si existen, solo quiero sacar el campo 1 al que le pertenece, como un ID

homy988 15-08-2018 01:21:38

Cita:

Empezado por ecfisa (Mensaje 528066)
Hola.

Extrayendo el código SQL queda:
Código SQL [-]
SELECT  MAX(campo1) AS a,
SELECT MAX(campo2) AS b
FROM tabla1
WHERE campo3 = 1 AND campo4 = 'texto' AND campo2 <6584651 
FROM CFDI
WHERE campo3=1 AND campo4= 'texto' AND campo2<:6584651
¿ Y no te arroja ningún error así como está ?

Saludos :)


no, no genera error, actualmente esta funcionando:

mira este es el código tal cual:

Código Delphi [-]
      qry.Close;
      qry.sql.clear;
      qry.sql.add('SELECT  MAX(campo1)AS a,');
      qry.sql.add('(SELECT MAX(campo2) AS b');
      qry.sql.add('FROM tabla1');
      qry.sql.add('WHERE campo3 =:valor1 AND campo4=:valor2 AND campo2<:valor3)');
      qry.sql.add('FROM CFDI');
      qry.sql.add('WHERE campo3 =:valor1 AND campo4=:valor2 AND campo2<:valor3');
      qry.ParamByName('valor1').AsFloat := valor1;
      qry.ParamByName('valor2').AsString :=valor2; 
      qry.ParamByName('valor3').AsFloat :=valor3;
      qry.open;

Casimiro Notevi 15-08-2018 11:16:54

Cita:

Empezado por homy988 (Mensaje 528067)
Mira, lo que pasa es no es que no se tenga, lo que pasa es que en su momento no se actualizo, por errores de conexión, sin embargo los datos si existen, solo quiero sacar el campo 1 al que le pertenece, como un ID

:confused: Mejores preguntas=mejores respuestas. Tenemos casi que estar adivinando.

TiammatMX 16-08-2018 21:05:09

Cita:

Empezado por homy988 (Mensaje 528022)
buenas tardes:

como puedo optimizar esta consulta...

¿Motor de base de datos? ¿Local, remota, web? ¿LAN, WAN, Internet?

De entrada, un subselect como el que me imagino tienes en la segunda línea SI ESTÁ PERFECTAMENTE PARAMETRIZADO no tarda mucho. No es lo mismo seleccionar una pelirroja con vestido blanco en una calle de Edimburgo que una pelirroja con vestido...

(Perdón por el ejemplo)

hal1967 20-08-2018 01:09:33

Este pedazo del código sería terrible (por lo menos en mysql)

Código Delphi [-]
qry.sql.add('(SELECT MAX(campo2) AS b');        

qry.sql.add('FROM tabla1');  

qry.sql.add('WHERE campo3=1 AND campo4= 'texto' AND campo2<6584651)');

MAX es genial en ciertos casos, porque el manejador de bb dd simplemente busca el ultimo registro del indice para esa columna, ni siquiera baja a disco (los indices están en ram), pero en el WHERE refieres al mismo campo (CAMPO 2) por lo que hay que recorrer el indice

Mi sugerencia es que pruebes un indice campo2, campo3, campo4 (siempre campo2 primero) y mides si ese subquery mejora

Yo de hecho cambiaría un poco la consulta (cosas de MySQL)

Código:

SELECT campo2
FROM tabla1
WHERE campo3=1 AND campo4= 'texto' AND campo2<6584651
ORDER BY campo2, campo3, campo4 DESC
LIMIT 1

Ahora fuera del subquery tienes
Código Delphi [-]
qry.sql.add('SELECT  MAX(campo1)AS a,');          

qry.sql.add('FROM CFDI');       
qry.sql.add('WHERE campo3 =:valor1 AND campo4=:valor2 AND campo2<:valor3');


Esto si es un dolor de cabeza, siempre termina por crear una tabla temporal y luego ordenarla. No importa lo que mejores el
subquery (por cierto no entiendo la función del subquery)


Lo seguiré pensando, pero realmente no veo forma de optimizar ese query.


La franja horaria es GMT +2. Ahora son las 14:01:11.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi