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 existait un commentaire sur le site Web de sqlite indiquant que si vous avez besoin d'une taille de fichier supérieure à 1 Go, vous pouvez envisager d'utiliser un fichier d'entreprise .dd. ne le trouve plus, peut-être lié à une ancienne version de sqlite).
Toutefois, je souhaiterais 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?
J'ai donc fait quelques tests avec sqlite pour de très gros fichiers et je suis parvenu à des conclusions (du 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 les entiers et 4 index.
L'idée était d'insérer suffisamment de données jusqu'à ce que les fichiers sqlite atteignent environ 50 Go.
Table unique
J'ai essayé d'insérer plusieurs lignes dans un fichier sqlite avec une seule table. Lorsque le fichier faisait environ 7 Go (désolé, je ne peux pas préciser 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.
Ceci m'amène à conclure qu'une seule et très grande table sqlite aura des problèmes d'insertion et probablement aussi d'autres opérations.
Je suppose que ce n’est pas une surprise, car la table s’agrandit, l’insertion et la mise à jour de tous les index prend plus de temps.
Plusieurs tables
J'ai ensuite essayé de scinder les données temporellement sur plusieurs tables, une table par jour. Les données de la table 1 originale ont été divisées en ~ 700 tables.
Cette configuration n’a posé aucun problème lors de l’insertion, elle n’a pas pris plus de temps, puisqu’un nouveau tableau a été créé pour chaque jour.
Problèmes de vide
Comme l'a souligné i_like_caffeine, la commande VACUUM pose un problème lorsque le fichier sqlite est volumineux. Avec la multiplication des insertions/suppressions, la fragmentation du fichier sur le disque s’aggravera. L’objectif est donc de procéder périodiquement à une opération VACUUM afin d’optimiser le fichier et de récupérer de l’espace.
Cependant, comme indiqué par documentation , une copie complète de la base de données est créée pour faire le vide, ce qui prend beaucoup de temps. Donc, plus la base de données est petite, plus cette opération se terminera rapidement.
Conclusions
Pour mon application spécifique, je vais probablement répartir les données sur plusieurs fichiers db, un par jour, pour obtenir le meilleur des performances du vide et de la vitesse d'insertion/suppression.
Cela complique les requêtes, mais pour moi, il est intéressant de pouvoir indexer autant de données. Un avantage supplémentaire est que je peux simplement supprimer un fichier de base de données complet pour supprimer une journée de données (opération courante pour mon application).
Je devrais probablement aussi surveiller la taille des tables par fichier pour voir quand la vitesse deviendrait un problème.
C'est dommage qu'il ne semble pas y avoir de méthode de vide incrémental autre que vide automatique . Je ne peux pas l'utiliser car mon objectif pour Vacuum est de défragmenter le fichier (l'espace fichier n'est pas grave), ce que ne fait pas Vacuum. En fait, la documentation indique que cela peut aggraver la fragmentation. Je dois donc périodiquement faire le vide complet dans le dossier.
Nous utilisons DBS de 50 Go + sur notre plateforme. pas se plaindre fonctionne très bien. Assurez-vous de tout faire correctement! Utilisez-vous des instructions prédéfinies? * SQLITE 3.7.3
Appliquer ces paramètres (juste après la création de la base de données)
PRAGMA main.page_size = 4096;
PRAGMA main.cache_size=10000;
PRAGMA main.locking_mode=EXCLUSIVE;
PRAGMA main.synchronous=NORMAL;
PRAGMA main.journal_mode=WAL;
PRAGMA main.cache_size=5000;
J'espère que cela aidera les autres, fonctionne très bien ici
J'ai créé des bases de données SQLite d'une taille allant jusqu'à 3,5 Go, sans aucun problème de performances notable. Si je me souviens bien, je pense que SQLite2 a peut-être eu des limites plus basses, mais je ne pense pas que SQLite3 pose 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 maximum de pages dans une base de données est 1024 ^ 3. Donc, selon mes calculs, la taille maximale est de 32 téraoctets. Je pense que vous allez atteindre les limites de votre système de fichiers avant de toucher SQLite!
La plupart des raisons pour lesquelles vos insertions ont pris> 48 heures sont dues à vos index. Il est incroyablement plus rapide de:
1 - Supprimer tous les index 2 - Effectuer toutes les insertions 3 - Créer à nouveau des index
Outre la recommandation habituelle:
J'ai appris ce qui suit de mon expérience avec SQLite3:
Question/commentaire bienvenue. ;-)
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.6s. Pour accélérer le processus, j'ai essayé d'ajouter des index. En fonction du ou des index que j'ai ajoutés, la requête est parfois descendue à 0.1s et parfois jusqu'à 7s. Je pense que le problème dans mon cas était que si une colonne est hautement dupliquée, l'ajout d'un index dégrade les performances :(
Je pense que les principales plaintes concernant la mise à l'échelle de sqlite sont les suivantes:
J'ai rencontré des problèmes avec les gros fichiers sqlite lors de l'utilisation de la commande vacuum.
Je n'ai pas encore essayé la fonctionnalité auto_vacuum. Si vous vous attendez à mettre à jour et à supprimer des données souvent, cela vaut la peine d'être examiné.