Gens,
Je travaille depuis un certain temps déjà sur des scripts de jointure non standard, et il semble que je devrai le faire beaucoup.
À ce stade, je dois joindre deux tables.
Le premier a une série de mesures sur différents outils. Les mesures sont effectuées en sessions. Mais la table contient uniquement les éléments suivants: outil, événement, résultat .
La deuxième table contient toutes les informations sur les sessions:
outil, sessionid, starttime, endtime
Et je dois faire l'analyse des mesures par ID de session
Fondamentalement, je dois rejoindre unique ID de session à chaque ligne du premier tableau.
Actuellement, je parcoure chaque ligne du premier tableau et cherche la ligne correspondante dans le second tableau où outil est apparié et heure de l'évènement est entre Heure de début et heure de fin en utilisant ceci:
currentStartEndInfoindex=dt2 << Get Rows Where(:tool==thisTool & :measstart < thisEventtime & :measend > thisEventtime);
où cet outil et thisEventtime sont l’outil et le moment de la première table que je parcoure. Je reçois des indeces de la liste avec unique ID de session à partir de la deuxième table qui remplit cette condition, puis créez-en une liste qui, à la fin de la boucle, est utilisée pour remplir la nouvelle colonne de la première table. Cette ligne "Get Rows Where" prend 85% du temps d'exécution du script.
Maintenant, avec quelques millions de lignes dans le premier tableau et des centaines de milliers dans le second, cela prend un peu entre 8 et 16 heures.
Je ne peux pas me permettre de courir aussi longtemps.
Par conséquent, question:
Est-il possible d'optimiser cela? Après tout, pour chaque ligne du premier tableau, il regarde encore et encore dans le second tableau - pas très efficace.
Une des idées que j'ai est de diviser la deuxième table en sous-listes par outil, puis de faire "Obtenir les lignes où" pour chaque ligne de la sous-liste correspondant à cet outil spécifique. Je ne sais pas comment le mettre en œuvre le meilleur, cependant.
Toute aide serait grandement appréciée.
Merci!
Voici une première approximation
aaa = New Table( "aaa", // the "event" table
Add Rows( 6 ),
New Column( "tool", Numeric, "Continuous", Format( "Best", 12 ), Set Values( [100, 100, 100, 200, 200, 200] ) ),
New Column( "eventtime", Numeric, "Continuous", Format( "Best", 12 ), Set Values( [11, 21, 12, 31, 41, 42] ) ),
New Column( "result", Numeric, "Continuous", Format( "Best", 12 ), Set Values( [0, 1, 1, 1, 0, 0] ) ),
New Column( "sessionID_added", Numeric, "Continuous", Format( "Best", 12 ), Set Selected, Set Values( [., ., ., ., ., .] ) )
);
bbb = New Table( "bbb", // the start-end table
Add Rows( 4 ),
New Column( "tool", Numeric, "Continuous", Format( "Best", 12 ), Set Values( [100, 100, 200, 200] ) ),
New Column( "sessionID", Numeric, "Continuous", Format( "Best", 12 ), Set Values( [111, 222, 333, 444] ) ),
New Column( "startTime", Numeric, "Continuous", Format( "Best", 12 ), Set Values( [10, 20, 30, 40] ) ),
New Column( "endTime", Numeric, "Continuous", Format( "Best", 12 ), Set Values( [19, 29, 39, 49] ) )
);
// build two lookup tables that find all the rows associated with a tool
aaaRowsFromTool = Associative Array();
For( irow = 1, irow <= N Rows( aaa ), irow++,
If( !(aaaRowsFromTool << Contains( aaa:tool[irow] )), //
aaaRowsFromTool[aaa:tool[irow]] = Eval List( {irow} )//
, //
Insert Into( aaaRowsFromTool[aaa:tool[irow]], irow ) //
)
);
bbbRowsFromTool = Associative Array();
For( irow = 1, irow <= N Rows( bbb ), irow++,
If( !(bbbRowsFromTool << Contains( bbb:tool[irow] )), //
bbbRowsFromTool[bbb:tool[irow]] = Eval List( {irow} )//
, //
Insert Into( bbbRowsFromTool[bbb:tool[irow]], irow ) //
)
);
toolList = bbbRowsFromTool << getkeys;
For( itool = 1, itool <= N Items( toolList ), itool += 1,
toolno = toolList[itool];
// build a sorted list of event times+row numbers for this tool
aaaRowList = aaaRowsFromTool[toolno];
aaa << selectrows( aaaRowList );
aaasub = aaa << Subset( Selected Rows( 1 ), Selected columns only( 0 ), link to original data table( 1 ) );
//aaasub << sort( by( eventTime ), replace table );
timeMatrix = aaasub:eventtime << getAsMatrix;
bbbRowList = bbbRowsFromTool[toolno];
For( irow = 1, irow <= N Items( bbbRowList ), irow += 1,
bbbRow = bbbRowList[irow];
start = bbb:startTime[bbbRow];
end = bbb:endTime[bbbRow];
id = bbb:sessionID[bbbRow];
// find the eventTimes between start and end, for this tool
//aaasub<<SELECTWHERE></SELECTWHERE>
Si cela fonctionne mais reste trop lent, vous voudrez peut-être tirer profit du tri de la table "event" par eventTime et remplacer le loc () par une recherche binaire.