SQL vers matrice<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />Salut tout le monde,
Est-il possible d'extraire des données d'une base de données directement dans une matrice sans les importer au préalable dans une table de données ?
Merci!
Re : SQL vers matricemerci pour ce commentaire.
J'ai un énorme ensemble de données de base de données de sociétés de cartes de crédit avec environ un million d'utilisateurs et quelques milliers d'observations pour chacun.
Je télécharge chaque utilisateur à la fois et j'analyse son modèle de comportement (c'est la grande boucle for).
Lorsque je l'exécute manuellement, un utilisateur à la fois, il fonctionne correctement. Lors de l'exécution de plus de 20 utilisateurs, il se bloque à un moment aléatoire sans aucune explication (le programme s'arrête simplement, ou j'obtiens le "jmp a effectué une violation d'accès"). Je continue d'améliorer mes commandes en termes de robustesse mais j'essaie toujours de trouver les maillons les plus faibles.
Ron
Re : SQL vers matriceJ'ai oublié de mentionner que l'utilisation de 'Select *' est un moyen sûr de tuer les performances de votre requête.L'utiliser dans une boucle for est une condamnation à mort.Ne devenez jamais paresseux en SQL, tapez toutes les colonnes que vous souhaitez extraire, même s'il s'agit de toutes les colonnes de la table.Vous verrez votre code s'exécuter plus rapidement à pas de géant.
Re : SQL vers matricemerci beaucoup,
maintenant mon script s'exécute beaucoup plus rapidement et a moins de problèmes.
Ron
Re : SQL vers matriceOuais, vous aurez besoin d'un insert d'eval, je ne pensais pas.
Re : SQL vers matriceVous avez besoin d'evalinsert car vous évaluez i à chaque fois dans la boucle.
Re : SQL vers matriceMerci msharp,
C'est très utile!
Mes instructions SQL n'étaient que des scripts bruts que j'ai copiés à partir de l'ouverture manuelle des tables.
Je pense que j'ai réussi à en obtenir la majeure partie, à l'exception de l'Eval Insert. Comment puis-je m'en passer ?
Ceci est mon script actuel.
connexion à la base de données = Créer une connexion à la base de données (
"DBQ=D:\MES DOCUMENTS\;DefaultDir=D:\MES DOCUMENTS\;Driver={Microsoft Text Driver (*.txt; *.csv)};DriverId=27;FIL=text;FILEDSN=D:\My Documents\SQLLog Data.dsn;MaxBufferSize=2048;MaxScanRows=8;PageTimeout=5;SafeTransactions=0;Threads=3;UID=admin;UserCommitSync=Oui ;"
) ;
// Extrait les numéros d'ID utilisateur dans une matrice :
Matrice utilisateur = ( dt100 = Exécuter SQL ( connexion à la base de données , "SELECT DISTINCT UserId FROM data.csv" , "dt10 - Liste d'ID d'utilisateur" , invisible )) << obtenir comme matrice ;
proche ( dt100 , Pas d'enregistrement ) ;
sqlstr = "SELECT * FROM data.csv où UserID = ^id^" ;
Pour ( je = 1 , je <= N lignes ( matrice d'utilisateurs ) , je ++,
identifiant = Matrice utilisateur [ je ] ;
dt10i = Exécuter SQL ( connexion à la base de données ,
Insertion d'évaluation ( sqlstr ) ,
"Journal de données utilisateur" || Carboniser ( je ) || " - " || Carboniser ( identifiant ) , invisible ) ;
// analyser la table de données //
proche ( dt10i , pas de sauvegarde ) ;
) ;
Fermer la connexion à la base de données ( connexion à la base de données ) ;
Re : SQL vers matriceQuelques choses.
Tout d'abord, modifiez votre première requête en "SELECT DISTINCT UserId From dataset.csv" ;
Cela fait deux choses, rend votre requête plus rapide et aussi puisque vous l'extrayez comme une matrice Usermatrix va maintenant = UniqueID couper plusieurs lignes de code. Cela supprime le besoin de stocker des listes et des matrices potentiellement très volumineuses qui ne sont pas utilisées (Userlist/UserMatrix).Juste mais sûr de changer nitems en nrows dans la boucle for.
Deuxièmement, il n'est pas nécessaire d'établir une connexion à la base de données à chaque fois dans votre boucle for.Utilisez dbconnection = créer une connexion à la base de données (dsn); où dsn est votre longue chaîne de requête ci-dessus.Ensuite, remplacez Open Database(...) par Execute SQL(dbconnection, sqlstr, "Log Data User " || Char(i), invisible).
Quelques points à retenir de cela, vous gagnerez du temps en vous connectant à la base de données à chaque fois (ce qui devrait vous faire gagner beaucoup de temps).Vous n'avez pas besoin d'évaluer insert() le sqlstr, ce n'est pas grave mais une étape de moins. Enfin, et ce qui est assez important, c'est que l'ouverture invisible de dt10i économisera beaucoup d'espace mémoire en aidant votre code à s'exécuter plus rapidement.Surtout si vous manipulez la table de données dans la partie "effectuer une analyse".Je vois que vous finissez par le fermer plus tard de toute façon.Pour accélérer l'exécution d'un script, il est important de se rappeler que toute table de données que vous envisagez de fermer doit être ouverte en mode invisible ou privé.
Assurez-vous d'avoir une connexion de fermeture de base de données( connexion à la base de données ); à la fin de votre code.
Re : SQL vers matriceMerci msharp,
J'aurais peut-être dû partager mon script avant.
Toute recommandation est la bienvenue.
Matrice utilisateur = ( dt100 = Ouvrir la base de données (
"DBQ=D:\MES DOCUMENTS;DefaultDir=D:\MES DOCUMENTS;Driver={Microsoft Text Driver (*.txt; *.csv)};DriverId=27;FIL=text;FILEDSN=D:\Mes Documents\ SQLLog Data.dsn;MaxBufferSize=2048;MaxScanRows=8;PageTimeout=5;SafeTransactions=0;Threads=3;UID=admin;UserCommitSync=Oui ;" ,
// la ligne suivante extraira uniquement l'ID utilisateur de l'ensemble de données pour réduire l'utilisation de la mémoire.
"SELECT UserId FROM dataset.csv" ,
"dt10 - Liste d'ID d'utilisateur" ,
invisible
// privé // cette option ne fonctionne pas !!!
)) << obtenir comme matrice ;
proche ( dt100 , Pas d'enregistrement ) ;
// identifier les utilisateurs et leur numéro d'identification
Liste d'utilisateur = Tableau associatif ( Matrice utilisateur ) ;
Identifiant unique = liste d'utilisateur << obtenir des clés ;
//
// c'est juste une déclaration dans une chaîne
sqlstr = "SELECT * FROM dataset.csv où id = ^i^" ;
// parcourt l'ensemble de données et extrait les données individuelles une par une.
Pour ( je = 1 , je <= N articles ( identifiant unique ) , je ++,
// extrait un journal personnel pour chaque utilisateur utilisant l'instruction.
dt10i = Ouvrir la base de données (
"DBQ=D:\MES DOCUMENTS;DefaultDir=D:\MES DOCUMENTS;Driver={Microsoft Text Driver (*.txt; *.csv)};DriverId=27;FIL=text;FILEDSN=D:\Mes Documents\ SQLLog Data.dsn;MaxBufferSize=2048;MaxScanRows=8;PageTimeout=5;SafeTransactions=0;Threads=3;UID=admin;UserCommitSync=Oui ;" ,
Insertion d'évaluation ( sqlstr ) ,
« Utilisateur de données de journal » || Carboniser ( je ) ,
) ;
// préforme l'analyse ...//
proche ( dt10i , pas de sauvegarde ) ;
) ;
Re : SQL vers matriceOn dirait que vous pourriez optimiser votre instruction SQL.
Quelque chose comme:
Avec IDtemp comme (sélectionnez IDcol dans IDtable où IDcol = 'FilterCriteria')
Sélectionnez * De la table ID
Inner Join IDtemp
Cela créera d'abord une table IDtemp temporaire que SQL utilise pour se joindre à la table ID plus grande.La jointure interne réduit considérablement la taille des tables avec lesquelles SQL doit travailler.Bien sûr, il peut y avoir des moyens plus simples de le rendre plus rapide.Tout dépend de la façon dont les données sont stockées et de la taille des tables.
Je me concentrerais sur l'optimisation de vos instructions SQL plutôt que sur l'optimisation de la manière dont JMP interagit et extrait les données.
Re : SQL vers matricemerci msharp,
cela me permet de comprendre que je n'ai rien raté.
Le fait est que la source de données est grande et j'ai seulement besoin d'obtenir une liste d'ID (une colonne). Après cela, j'extrait les données (plusieurs colonnes) pour chaque ID et je les analyse séparément. ouvrir l'ensemble des données n'est tout simplement pas faisable.
Ron
Re : SQL vers matriceEh bien, oui et non. Vous pouvez l'importer directement dans JSL sous forme de matrice en utilisant :
matrix = Execute SQL(dsn, sql_string, table_name, invisible) << Get as matrix ;
Cependant, l'instruction SQL d'exécution crée toujours une table de données. Si "privé" était une option, cela serait possible car JMP efface automatiquement les tables de données privées de la mémoire de votre ordinateur si elles ne sont pas stockées quelque part. Hélas, l'invisible est ce qu'ils nous offrent de mieux.
Vous pouvez utiliser le script ci-dessous pour fermer la table invisible.En pratique, ce sera tout aussi rapide car l'exécution de l'instruction SQL sera toujours le goulot d'étranglement.
matrice = (dt = Execute SQL(dsn, sql_string, table_name, invisible)) << Get as matrix;
fermer(dt);