Je sais que sqlite ne fonctionne pas bien avec des fichiers de base de données extrêmement volumineux même lorsqu'ils sont pris en charge (il y avait un commentaire sur le site Web sqlite indiquant que si vous avez besoin de tailles de fichier supérieures à 1 Go, vous pouvez envisager d'utiliser un rdbms d'entreprise. ne le trouve plus, peut être lié à une ancienne version de sqlite).
Cependant, pour mes besoins, j'aimerais avoir une idée de la gravité de la situation avant d'envisager d'autres solutions.
Je parle de fichiers de données sqlite dans la plage de plusieurs gigaoctets, à partir de 2 Go. Quelqu'un a-t-il une expérience avec ceci? Des conseils / idées?
database
performance
sqlite
Snazzer
la source
la source
Réponses:
J'ai donc fait quelques tests avec sqlite pour les très gros fichiers, et je suis parvenu à des conclusions (au moins pour mon application spécifique).
Les tests impliquent un seul fichier sqlite avec une seule table ou plusieurs tables. Chaque table avait environ 8 colonnes, presque tous des entiers et 4 indices.
L'idée était d'insérer suffisamment de données jusqu'à ce que les fichiers sqlite mesurent environ 50 Go.
Table simple
J'ai essayé d'insérer plusieurs lignes dans un fichier sqlite avec une seule table. Lorsque le fichier était d'environ 7 Go (désolé, je ne peux pas être précis sur le nombre de lignes), les insertions prenaient beaucoup trop de temps. J'avais estimé que mon test pour insérer toutes mes données prendrait environ 24 heures, mais il ne s'est pas terminé même après 48 heures.
Cela m'amène à conclure qu'une seule table sqlite très grande aura des problèmes avec les insertions, et probablement d'autres opérations également.
Je suppose que ce n'est pas une surprise, car le tableau s'agrandit, l'insertion et la mise à jour de tous les indices prennent plus de temps.
Tables multiples
J'ai ensuite essayé de diviser les données par le temps sur plusieurs tables, une table par jour. Les données du tableau 1 d'origine ont été divisées en ~ 700 tableaux.
Cette configuration n'a eu aucun problème avec l'insertion, elle n'a pas pris plus de temps avec le temps, car une nouvelle table a été créée pour chaque jour.
Problèmes de vide
Comme l'a souligné i_like_caffeine, la commande VACUUM est un problème plus le fichier sqlite est volumineux. Au fur et à mesure que plus d'insertions / suppressions sont effectuées, la fragmentation du fichier sur le disque va s'aggraver, donc l'objectif est de périodiquement VACUUM pour optimiser le fichier et récupérer l'espace du fichier.
Cependant, comme le souligne la documentation , une copie complète de la base de données est réalisée pour faire le vide, ce qui prend beaucoup de temps. Ainsi, plus la base de données est petite, plus cette opération se terminera rapidement.
Conclusions
Pour mon application spécifique, je répartirai probablement les données sur plusieurs fichiers db, un par jour, pour obtenir le meilleur des performances de vide et de la vitesse d'insertion / suppression.
Cela complique les requêtes, mais pour moi, c'est un compromis intéressant de pouvoir indexer autant de données. Un avantage supplémentaire est que je peux simplement supprimer un fichier db entier pour supprimer une journée de données (une opération courante pour mon application).
Je devrais probablement également surveiller la taille de la table par fichier pour voir quand la vitesse deviendra un problème.
Il est dommage qu'il ne semble pas y avoir de méthode de vide incrémentielle autre que le vide automatique . Je ne peux pas l'utiliser car mon objectif pour le vide est de défragmenter le fichier (l'espace fichier n'est pas un gros problème), ce que le vide automatique ne fait pas. En fait, la documentation indique que cela peut aggraver la fragmentation, je dois donc recourir périodiquement à un vide complet sur le fichier.
la source
Nous utilisons DBS de 50 Go + sur notre plateforme. aucune plainte fonctionne très bien. Assurez-vous que vous faites tout correctement! Utilisez-vous des instructions prédéfinies? * SQLITE 3.7.3
Appliquer ces paramètres (juste après avoir créé la base de données)
J'espère que cela aidera les autres, fonctionne très bien ici
la source
PRAGMA main.temp_store = MEMORY;
.J'ai créé des bases de données SQLite d'une taille maximale de 3,5 Go sans problèmes de performances notables. Si je me souviens bien, je pense que SQLite2 aurait pu avoir des limites inférieures, mais je ne pense pas que SQLite3 ait de tels problèmes.
Selon la page SQLite Limits , la taille maximale de chaque page de base de données est de 32 Ko. Et le nombre maximum de pages dans une base de données est de 1024 ^ 3. Donc, d'après mes calculs, cela fait 32 téraoctets comme taille maximale. Je pense que vous atteindrez les limites de votre système de fichiers avant de toucher à SQLite!
la source
Une grande partie de la raison pour laquelle il a fallu plus de 48 heures pour faire vos insertions est à cause de vos index. Il est incroyablement plus rapide de:
1 - Supprimer tous les index 2 - Faire toutes les insertions 3 - Créer à nouveau des index
la source
Outre la recommandation habituelle:
J'ai appris ce qui suit de mon expérience avec SQLite3:
Modifier la table plus tard si nécessaireVous ne pouvez pas ajouter de contraintes avec ALTER TABLE).Bienvenue question / commentaire. ;-)
la source
Je pense que les principales plaintes concernant la mise à l'échelle sqlite sont les suivantes:
la source
J'ai une base de données SQLite de 7 Go. Pour effectuer une requête particulière avec une jointure interne, il faut 2,6 secondes. Pour accélérer cela, j'ai essayé d'ajouter des index. Selon le ou les index que j'ai ajoutés, parfois la requête descendait à 0,1 s et parfois elle montait jusqu'à 7 s. Je pense que le problème dans mon cas était que si une colonne est très en double, l'ajout d'un index dégrade les performances :(
la source
Il y avait auparavant une déclaration dans la documentation SQLite selon laquelle la limite de taille pratique d'un fichier de base de données était de quelques dizaines de Go: s. Cela était principalement dû à la nécessité pour SQLite «d'allouer un bitmap de pages sales» chaque fois que vous avez commencé une transaction. Ainsi, 256 octets de RAM étaient nécessaires pour chaque Mo de la base de données. L'insertion dans un fichier DB de 50 Go nécessiterait un lourd (2 ^ 8) * (2 ^ 10) = 2 ^ 18 = 256 Mo de RAM.
Mais depuis les versions récentes de SQLite, cela n'est plus nécessaire. Lisez plus ici .
la source
2^18
s'agit en fait que de 256 K.J'ai rencontré des problèmes avec de gros fichiers sqlite lors de l'utilisation de la commande vacuum.
Je n'ai pas encore essayé la fonction auto_vacuum. Si vous prévoyez de mettre à jour et de supprimer des données souvent, cela vaut la peine d'être examiné.
la source