SQL a matriz<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />Hola a todos,
¿Es posible extraer datos de una base de datos directamente a una matriz sin importarlos primero a una tabla de datos?
¡Gracias!
Re: SQL a matrizgracias por este comentario
Tengo un enorme conjunto de datos de la base de datos de la compañía de tarjetas de crédito con alrededor de un millón de usuarios y un par de miles de observaciones para cada uno.
Descargo a cada usuario a la vez y analizo su patrón de comportamiento (este es el bucle grande).
Cuando lo ejecuto manualmente, un usuario a la vez, funciona bien. Cuando se ejecutan más de 20 usuarios, se bloquea en un punto aleatorio sin ninguna explicación (el programa simplemente se cierra o aparece el mensaje "jmp ha realizado una infracción de acceso"). sigo mejorando mis comandos en términos de robustez, pero sigo tratando de encontrar los eslabones más débiles.
Ron
Re: SQL a matrizOlvidé mencionar que usar 'Seleccionar *' es una forma segura de matar el rendimiento de su consulta.Usarlo en un bucle for es una sentencia de muerte.Nunca se vuelva perezoso en SQL, escriba todas las columnas que desea extraer, incluso si se trata de todas las columnas de la tabla.Verá que su código se ejecuta más rápido a pasos agigantados.
Re: SQL a matrizMuchísimas gracias,
ahora mi secuencia de comandos se ejecuta mucho más rápido y tiene menos problemas.
Ron
Re: SQL a matrizSí, necesitarás una inserción de evaluación, no estaba pensando.
Re: SQL a matrizNecesita evalinsert porque está evaluando i cada vez que pasa por el ciclo.
Re: SQL a matrizGracias,
¡Esto es muy útil!
Mis declaraciones SQL eran solo scripts crudos que copié de la apertura manual de las tablas.
Creo que me las arreglé para obtener la mayor parte excepto por el inserto de evaluación. ¿Cómo me las arreglo sin él?
Este es mi guión actual.
dbconexión = Crear conexión de base de datos (
"DBQ=D:\MIS DOCUMENTOS\;DefaultDir=D:\MIS DOCUMENTOS\;Driver={Microsoft Text Driver (*.txt; *.csv)};DriverId=27;FIL=texto;FILEDSN=D:\Mi Documentos\SQLLog Data.dsn;MaxBufferSize=2048;MaxScanRows=8;PageTimeout=5;SafeTransactions=0;Threads=3;UID=admin;UserCommitSync=Yes;"
) ;
// Extrae los números de ID de usuario en una matriz:
matriz de usuario = ( dt100 = Ejecutar SQL ( dbconexión , "SELECCIONE ID DE USUARIO DISTINTO DE data.csv" , "dt10 - Lista de ID de usuario" , invisible )) << obtener como matriz ;
Cerca ( dt100 , NoGuardar ) ;
sqlstr = "SELECCIONE * DESDE data.csv donde ID de usuario = ^id^" ;
Para ( i = 1 , i <= n filas ( matriz de usuario ) , i ++,
identificación = matriz de usuario [ i ] ;
dt10i = Ejecutar SQL ( dbconexión ,
Insertar evaluación ( sqlstr ) ,
"Registro de datos de usuario" || Carbonizarse ( i ) || "-" || Carbonizarse ( identificación ) , invisible ) ;
// analiza la tabla de datos //
Cerca ( dt10i , sin guardar ) ;
) ;
Cerrar conexión de base de datos ( dbconexión ) ;
Re: SQL a matrizUn par de cosas.
Primero, cambie su primera consulta a "SELECCIONE ID de usuario DISTINTO de dataset.csv";
Esto hace dos cosas, hace que su consulta sea más rápida y también, dado que la está extrayendo como una matriz, Usermatrix ahora = UniqueID cortando varias líneas de código. Esto elimina la necesidad de almacenar listas y matrices potencialmente muy grandes que no se utilizan (Lista de usuarios/Matriz de usuarios).Solo pero seguro de cambiar nitems a nrows en el ciclo for.
En segundo lugar, no es necesario establecer una conexión con la base de datos cada vez que se realiza un bucle for.Use dbconnection = crear conexión de base de datos (dsn); donde dsn es su larga cadena de consulta anterior.Luego cambie Abrir base de datos (...) para Ejecutar SQL (conexión db, sqlstr, "Usuario de datos de registro" || Char (i), invisible).
Un par de conclusiones de esto, ahorrará tiempo al conectarse a la base de datos cada vez (lo que debería ahorrar mucho tiempo).No necesita evaluar insert() el sqlstr, no es gran cosa, pero es un paso menos. Por último, y bastante importante, es que abrir dt10i de forma invisible ahorrará mucho espacio en la memoria, lo que ayudará a que su código se ejecute más rápido.Especialmente si manipula la tabla de datos en la parte "realizar análisis".Veo que terminas cerrándolo más tarde de todos modos.Para hacer que un script se ejecute más rápido, es importante recordar que cualquier tabla de datos que planee cerrar debe abrirse en modo invisible o privado.
Asegúrese de tener una conexión de base de datos cercana ( dbconexión ); al final de su código.
Re: SQL a matrizGracias,
Tal vez debería haber compartido mi guión antes.
Cualquier recomendación es bienvenida.
matriz de usuario = ( dt100 = Abrir base de datos (
"DBQ=D:\MIS DOCUMENTOS;DefaultDir=D:\MIS DOCUMENTOS;Driver={Microsoft Text Driver (*.txt; *.csv)};DriverId=27;FIL=texto;FILEDSN=D:\Mis documentos\ SQLLog Data.dsn;MaxBufferSize=2048;MaxScanRows=8;PageTimeout=5;SafeTransactions=0;Threads=3;UID=admin;UserCommitSync=Yes;" ,
// la siguiente línea extraerá solo el ID de usuario del conjunto de datos para reducir el uso de memoria.
"SELECCIONE ID de usuario DESDE dataset.csv" ,
"dt10 - Lista de ID de usuario" ,
invisible
// privado // ¡¡¡esta opción no funciona!!!
)) << obtener como matriz ;
Cerca ( dt100 , NoGuardar ) ;
// identificar a los usuarios y su número de identificación
Lista de usuarios = matriz asociativa ( matriz de usuario ) ;
Identificación única = Lista de usuarios << conseguir llaves ;
//
// esto es solo una declaración en una cadena
sqlstr = "SELECCIONE * DESDE dataset.csv donde id = ^i^" ;
// recorrer el conjunto de datos y extraer datos individuales uno a la vez.
Para ( i = 1 , i <= N elementos ( Identificación única ) , i ++,
// extrae un registro personal para cada usuario que usa la declaración.
dt10i = Abrir base de datos (
"DBQ=D:\MIS DOCUMENTOS;DefaultDir=D:\MIS DOCUMENTOS;Driver={Microsoft Text Driver (*.txt; *.csv)};DriverId=27;FIL=texto;FILEDSN=D:\Mis documentos\ SQLLog Data.dsn;MaxBufferSize=2048;MaxScanRows=8;PageTimeout=5;SafeTransactions=0;Threads=3;UID=admin;UserCommitSync=Yes;" ,
Insertar evaluación ( sqlstr ) ,
"Usuario de datos de registro" || Carbonizarse ( i ) ,
) ;
// realizar el análisis...//
cerca ( dt10i , sin guardar ) ;
) ;
Re: SQL a matrizParece que podría optimizar su declaración SQL.
Algo como:
Con IDtemp como (Seleccione IDcol de IDtable donde IDcol = 'FilterCriteria')
Seleccione * De la tabla de ID
IDtemp de unión interna
Esto primero creará una tabla IDtemp temporal que SQL usa para unirse con la tabla ID más grande.La combinación interna reduce en gran medida el tamaño de las tablas con las que SQL tiene que trabajar.Por supuesto, puede haber formas más simples de hacerlo más rápido.Todo depende de cómo se almacenan los datos y qué tan grandes son las tablas.
Me centraría en optimizar sus declaraciones SQL en lugar de optimizar cómo JMP interactúa y extrae los datos.
Re: SQL a matrizgracias mssharp,
esto me aclara que no me perdí nada.
El problema es que la fuente de datos es grande y solo necesito obtener una lista de ID (una columna). Después de eso, extraigo los datos (muchas columnas) para cada ID y los analizo por separado. abrir todo el conjunto de datos simplemente no es factible.
Ron
Re: SQL a matrizBueno, sí y no. Puede importarlo directamente a JSL como una matriz usando:
matriz = Ejecutar SQL(dsn, sql_string, table_name, invisible) << Obtener como matriz;
Sin embargo, la instrucción SQL de ejecución aún crea una tabla de datos. Si "privado" fuera una opción, entonces sería posible ya que JMP borra automáticamente las tablas de datos privadas de la memoria de su computadora si no están almacenadas en algún lugar. Ay, invisible es lo mejor que nos dan.
Puede usar el siguiente script para cerrar la tabla invisible.En la práctica, será igual de rápido, ya que ejecutar la instrucción SQL siempre será el cuello de botella.
matriz = (dt = Ejecutar SQL(dsn, sql_string, table_name, invisible)) << Obtener como matriz;
cerrar(dt);