Ou devrais-je utiliser un autre marteau pour résoudre ce problème.
J'ai une utilisation très simple-cas pour le stockage des données, de manière efficace d'une matrice creuse, que j'ai tenté de stocker dans une base de données SQLite. J'ai créé un tableau:
create TABLE data ( id1 INTEGER KEY, timet INTEGER KEY, value REAL )
dans lequel j'ai insérer un grand nombre de données, (800 éléments, toutes les 10 minutes, 45 fois par jour), la plupart des jours de l'année. Le n-uplet de (id1,préventive) sera toujours unique.
L'préventive valeur est en secondes depuis l'epoch, et sera toujours en augmentation. Le id1 est, à toutes fins pratiques, un entier aléatoire. Il n'y a probablement que 20000 id unique bien.
Alors je dirais comme d'accéder à toutes les valeurs où id1==someid ou accès à tous les éléments où préventive==de temps en temps. Sur mes tests à l'aide de la dernière SQLite via l'interface C sur Linux, recherche pour l'un de ces (ou toute variante de cette recherche) prend environ 30 secondes, ce qui n'est pas assez rapide pour mon cas d'utilisation.
J'ai essayé de définir un index de la base de données, mais cela a ralenti le curseur d'insertion complètement impraticable vitesses (j'ai peut-être fait de cette manière incorrecte si...)
Le tableau ci-dessus conduit à de très lent d'accès pour toutes les données. Ma question est:
- Est SQLite complètement le mauvais outil pour cela?
- Puis-je définir des indices pour accélérer les choses de manière significative?
- Dois-je utiliser quelque chose comme HDF5 au lieu de SQL pour cela?
Veuillez excuser mon très compréhension de base de SQL!
Merci
- Je inclure un exemple de code qui montre comment l'insertion de la vitesse ralentit énormément lors de l'utilisation d'indices. Avec la 'création d'un" indice de déclarations en place, le code prend en 19 minutes. Sans cela, il s'exécute en 18 secondes.
#include <iostream>
#include <sqlite3.h>
void checkdbres( int res, int expected, const std::string msg )
{
if (res != expected) { std::cerr << msg << std::endl; exit(1); }
}
int main(int argc, char **argv)
{
const size_t nRecords = 800*45*30;
sqlite3 *dbhandle = NULL;
sqlite3_stmt *pStmt = NULL;
char statement[512];
checkdbres( sqlite3_open("/tmp/junk.db", &dbhandle ), SQLITE_OK, "Failed to open db");
checkdbres( sqlite3_prepare_v2( dbhandle, "create table if not exists data ( issueid INTEGER KEY, time INTEGER KEY, value REAL);", -1, & pStmt, NULL ), SQLITE_OK, "Failed to build create statement");
checkdbres( sqlite3_step( pStmt ), SQLITE_DONE, "Failed to execute insert statement" );
checkdbres( sqlite3_finalize( pStmt ), SQLITE_OK, "Failed to finalize insert");
checkdbres( sqlite3_prepare_v2( dbhandle, "create index issueidindex on data (issueid );", -1, & pStmt, NULL ), SQLITE_OK, "Failed to build create statement");
checkdbres( sqlite3_step( pStmt ), SQLITE_DONE, "Failed to execute insert statement" );
checkdbres( sqlite3_finalize( pStmt ), SQLITE_OK, "Failed to finalize insert");
checkdbres( sqlite3_prepare_v2( dbhandle, "create index timeindex on data (time);", -1, & pStmt, NULL ), SQLITE_OK, "Failed to build create statement");
checkdbres( sqlite3_step( pStmt ), SQLITE_DONE, "Failed to execute insert statement" );
checkdbres( sqlite3_finalize( pStmt ), SQLITE_OK, "Failed to finalize insert");
for ( size_t idx=0; idx < nRecords; ++idx)
{
if (idx%800==0)
{
checkdbres( sqlite3_prepare_v2( dbhandle, "BEGIN TRANSACTION", -1, & pStmt, NULL ), SQLITE_OK, "Failed to begin transaction");
checkdbres( sqlite3_step( pStmt ), SQLITE_DONE, "Failed to execute begin transaction" );
checkdbres( sqlite3_finalize( pStmt ), SQLITE_OK, "Failed to finalize begin transaction");
std::cout << "idx " << idx << " of " << nRecords << std::endl;
}
const size_t time = idx/800;
const size_t issueid = idx % 800;
const float value = static_cast<float>(rand()) / RAND_MAX;
sprintf( statement, "insert into data values (%d,%d,%f);", issueid, (int)time, value );
checkdbres( sqlite3_prepare_v2( dbhandle, statement, -1, &pStmt, NULL ), SQLITE_OK, "Failed to build statement");
checkdbres( sqlite3_step( pStmt ), SQLITE_DONE, "Failed to execute insert statement" );
checkdbres( sqlite3_finalize( pStmt ), SQLITE_OK, "Failed to finalize insert");
if (idx%800==799)
{
checkdbres( sqlite3_prepare_v2( dbhandle, "END TRANSACTION", -1, & pStmt, NULL ), SQLITE_OK, "Failed to end transaction");
checkdbres( sqlite3_step( pStmt ), SQLITE_DONE, "Failed to execute end transaction" );
checkdbres( sqlite3_finalize( pStmt ), SQLITE_OK, "Failed to finalize end transaction");
}
}
checkdbres( sqlite3_close( dbhandle ), SQLITE_OK, "Failed to close db" );
}