Abrir tablas o
no abrir tablas. Esa es la pregunta.
por Jim Booth (Publicado originalmente en FoxTALK Diciembre 1998)
por Jim Booth (Publicado originalmente en FoxTALK Diciembre 1998)
Traducido por Roberto Alfredo Moré
¿Se ha preguntado alguna vez si hay algún beneficio abriendo
las tablas para un comando SQL SELECT antes de ejecutar el SELECT?. ¿Usa el
SELECT las tablas que ya están abiertas?. Interesante pregunta.¿Qué tan rápido es rápido?
Una simple prueba para averiguar cuál es el efecto de abrir primero las tablas sobre la performance de SQL en Visual FoxPro se muestra en el siguiente ejemplo de código.
LPARAMETERS plCloseThemEn el programa de prueba de arriba, la tabla BigFile es una tabla de 200,000 registros con índices sobre el campo cState y sobre DELETED(). El programa puede ser llamado con un parámetro que le indica si cierra o no las tablas entre las corridas del comando SELECT. Ejecuta el SELECT 100 veces y luego promedia el tiempo que toma el SELECT.
DIMENSION laTimes(100)
FOR lnCnt = 1 TO 100
lnStart = SECONDS()
SELECT * FROM BigFile WHERE cState = "NY" INTO CURSOR Result
lnEnd = SECONDS()
laTimes(lnCnt) = lnEnd - lnStart
IF plCloseThem
CLOSE ALL
ENDIF
ENDFOR
* Calcular el tiempo promedio
lnTime = 0
FOR lnCnt = 1 TO 100
lnTime = lnTime + laTimes(lnCnt)
ENDFOR
lnTime = lnTime/100
?lnTime
En mi máquina (Pentium II 300MHz con 128 MB RAM y un disco rígido SCSI) obtuve un promedio de tiempo de 1.23 segundos cuando las tablas se cierran entre los SELECTS. Si las tablas se dejan abiertas, el tiempo promedio fue de 0.67 segundos, ¡dos veces más rápido!.
Conclusión: Abra sus tablas primero y déjelas abiertas, especialmente si estará ejecutando múltiples SELECTS que acceden a estas tablas.
¿Usa realmente el SELECT las tablas que están abiertas?
No, no las usa. Utiliza un USE AGAIN para abrir la tabla en otra área de trabajo. Para ver esto, usted puede realizar la siguiente prueba:
1. Abra la ventana Data Session desde el menú Window.Encontrará que la segunda vez hay un hueco en las áreas de trabajo que usó el comando SELECT. Si usted hace esto cuando no hay ninguna tabla abierta, la primera vez las áreas de trabajo deberían ser 1 para la tabla origen y 2 para el resultado. La segunda vez, serían 1 para la tabla origen y 3 para el resultado.
2. En la ventana de comandos ejecute un comando SELECT simple como SELECT * FROM AlgunaTabla INTO CURSOR Resultado.
3. En la ventana Data Session haga click sobre el nombre de la tabla origen y observe el eco del comando en la ventana de comandos (será SELECT 1 o algo así). El número es el área de trabajo en que el cursor está abierto.
4. Haga click sobre el cursor Resultado y observe el área de trabajo (podría ser 2).
5. Tipee USE en la ventana de comandos para cerrar el cursor Resultado.
6. Corra nuevamente el comando SELECT.
7. Repita los pasos 3. y 4. nuevamente.
La razón por la que el resultado está en un área de trabajo diferente la segunda vez es que el SELECT abrió la tabla origen en el área 2 durante el proceso de consulta. Esto fue hecho con una operación USE AGAIN. El beneficio de este comportamiento son dos cosas:
1) el segundo SELECT se ejecutará más rápido y¿Por qué es más rápido abrir las tablas?
2) el puntero de registro en el área de trabajo de la tabla origen no se afecta.
Porque cuando una tabla está abierta, con SET OPTIMIZE ON, VFP trata de capturar tanto como pueda del índice para proveer a Rushmore con lo que necesita. Así, cada vez que se abre una tabla, se lee en memoria una cierta cantidad de información. Cuando se usa USE AGAIN para una tabla que ya está abierta, esa información ya está en memoria y no necesita ser leída del disco. Usted habrá notado, en el programa de prueba, que no hay un comando USE Bigfile. Esto ilustra otra sutil cualidad del comando SQL SELECT. Si se ejecuta el SELECT y la(s) tabla(s) de origen no está(n) abierta(s), la(s) abrirá y la(s) mantendrá abierta(s). Si la(s) tabla(s) de origen está(n) abierta(s), las usará nuevamente en otra área de trabajo y cerrará dicha área de trabajo cuando se completa el SELECT.
Una nota final.
Hay una preocupación reciente sobre el uso de SYS(2015) para generar nombres únicos de cursor. Existe un informe sobre que SUBSTR(SYS(2015),3) comenzará con un dígito en un futuro cercano. Bueno, esto es cierto, pero es irrelevante. Los cursores creados con el comando SQL SELECT o CREATE CURSOR usan el nombre para definir el alias del área de trabajo donde se ubica el cursor, NO el nombre del archivo en disco usado por el cursor para sus datos. Los nombres de archivo para los cursores serán siempre únicos y se crearán en el directorio temporal del usuario. Los nombres alias son siempre locales al equipo actual y no necesitan ser únicos. Pruebe lo siguiente en una ventana de comandos:
CREATE CURSOR MyCsr (Test C(10))Lo que se obtiene como resultado de Alias() es MyCsr y DBF() es C:Temp2E4H000C.TMP. De aquí se puede deducir que
? ALIAS()
?DBF()
1) el archivo para el cursor fue creado en el directorio temporal, no en el disco de red, yNo es necesario usar ningún algoritmo para crear un nombre único de un cursor; usted puede usar nombres significativos en su código y no encontrará problemas en un entorno multiusuario.
2) el nombre utilizado en el comando CREATE CURSOR no es el mismo que el que se usó en el archivo dbf.