10
votes

SQLite: Quelles sont les limites pratiques?

Avant de marquer cette question en tant que duplicata, veuillez m'en entendre !!
J'ai déjà lu les questions posées ici sur la manière d'améliorer la performance par exemple. Juste pour mentionner quelques Améliorer les performances d'insertion par seconde de sqlite? et Quelles sont les caractéristiques de performance de SQLite avec de très grands fichiers de base de données?

Je suis en difficulté pour faire du travail SQLite avec la taille de fichier de base de données de 5 gigaoctets. Au contraire, il y a des gens là-bas, qui prétendent que SQLite fonctionne 'super' pour eux même lorsque la taille de la base de données est aussi importante que 160 Go. Je n'ai pas essayé moi-même mais des questions posées, je suppose que tout le marquage bancaire est peut-être fait avec seulement une table dans la base de données.

J'utilise une base de données avec
- 20 ou tonnes tables
- la moitié des tables ont plus de 15 colonnes
- Chacune de ces tables de 15 ou so-colonnes a 6/7 colonnes à clé étrangère - Quelques-uns de ces table ont déjà augmenté pour avoir 27 millions d'enregistrements avec un mois

La machine de développement que j'utilise est la machine de 3 GHz Quad Core avec 4 concerts de RAM et il faut encore plus de 3 minutes pour interroger le Row_Count dans ces grandes tables.

Je n'ai trouvé aucun moyen de partitionner les données horizontalement. Le meilleur tir que j'ai est de diviser les données sur plusieurs fichiers de base de données une pour chaque table. Mais dans ce cas, autant que je sache, les contraintes de la colonne de la clé étrangère ne peuvent pas être utilisées. Je vais donc devoir créer une table autonome (sans aucune clé étrangère).

Alors mes questions sont
a) Est-ce que j'utilise la mauvaise base de données pour le travail?
b) Que pensez-vous où je vais mal?
c) Je n'ai pas encore ajouté d'index sur les clés étrangères, mais si juste une question de comptage de ligne prend quatre minutes, comment les index des clés étrangères me vont-ils m'aider?

éditer Fournir plus d'informations, même si personne ne l'a demandé :) J'utilise SQLite version 3.7.9 avec système.data.sqlite.dll version 1.0.77.0

EDIT2: Je pense que lorsque je vais différemment des 160 gigues, c'est qu'ils peuvent sélectionner un enregistrement individuel ou une petite gamme d'enregistrements. Mais je dois charger toutes les 27 millions de lignes de ma table, les rejoindre contre d'autres tables, regroupez les enregistrements comme demandé par l'utilisateur et renvoyer les résultats. Toute entrée sur le meilleur moyen d'optimiser la base de données pour de tels résultats.

Je ne peux pas mettre en cache les résultats d'une requête précédente car il n'a pas de sens dans mon cas. Les chances de frapper le cache seront assez basses.


9 commentaires

Si d'autres disent que 160 Go de bases de données fonctionnent bien, il doit clairement être quelque chose que vous faites, mais vous ne nous disez pas comment vous faites des choses, sauf pour dire que vous n'avez pas d'index sur les clés étrangères. Avez-vous essayé indexer les clés étrangères?


Selon les questions posées, je suppose que 160 Go de bases de données utilisaient une seule table. Non, je n'ai pas encore ajouté d'index sur les clés étrangères, car même lorsque j'exécute une requête où les clés étrangères ne sont pas impliquées, c'est non impliqué, c'est-à-dire (*) de quelque_table ', SQLite prend des minutes pour renvoyer le résultat de cette requête. J'ajouterai des index aux clés étrangères et je vais récupérer. S'il vous plaît laissez-moi savoir quelle plus d'informations voudriez-vous savoir.


Avez-vous des index sur les tables?


La lecture des millions de lignes du disque dur pourrait prendre un certain temps, mais les lectures ultérieures devraient être beaucoup plus rapides, en fonction de la mémoire disponible du système.


Oui, les champs les plus couramment utilisés dans les requêtes par ex. Date heure, ils sont indexés. Je n'ai pas tout indexé est le premier endroit car il devrait ralentir les inserts.


@Nick Dandoulakis: Ce que j'ai remarqué, c'est qu'il y a trop de défaillances de page sur mon processus, même si l'utilisation de la mémoire de mon processus n'est pas si élevée et selon la tâche, j'ai encore environ 1 gigaoctet de mémoire libre


La seule chose que vous pourriez essayer qui avait réduit le temps d'exécution de certaines requêtes SQLite pour moi est pragma cache_size = 16000 (ceci a réduit un processus qui prenait plus de 20 minutes à moins de 2 minutes), vous pouvez utiliser un valeur supérieure si nécessaire, mais être averti que la valeur est dans les pages afin que la mémoire utilisée soit cache_size in pages fois _ in bytes_


J'utilise déjà les directives de pragma suivantes. Pragma journal_mode = wal; Pragma page_size = 4096; Pragma cache_size = 10000; Pragma verrouillant_mode = exclusif; Pragma synchrones = normal; Pragma Count_changes = OFF; Pragma temp_store = mémoire; La chose qui me bugs est que si j'exécute une requête sur l'une des plus grandes tables, les lectures d'E / S pour mon processus ne se présentent jamais à un stand.


Stackoverflow.com/questions/14451624/... | Stackoverflow.com/questions/2777954/...


3 Réponses :


6
votes

Il y a beaucoup à considérer ici, mais mon premier conseil ne serait pas de ne pas prendre les statistiques de performance d'autres à la valeur faciale. Les performances de la base de données dépendent de nombreuses choses, notamment la structure de votre base de données, la complexité de vos requêtes, qui index que vous avez définies (ou non) et souvent juste la quantité de données pure de données. Beaucoup de numéros de performance rapportés provient de nombreux essais et erreurs, et / ou correspondant à la base de données au travail à portée de main. Pour le dire une autre manière, les performances que vous allez obtenir de n'importe quel SGBD ne peuvent être comparées clairement à la performance d'une autre application à moins que vos jeux de données et vos structures ne soient pratiquement identiques - ils sont certainement un guide, et peut-être un idéal pour s'efforcer , mais vous n'allez pas nécessairement obtenir des performances folles «hors de la boîte».

Je ferais, comme point de départ, commencez à indexer les données sur ces tables vraiment grandes (regards, des commentaires, que vous avez cela), et voyez ce qui se passe. Certes, le nombre de personnes prenant quatre minutes est une assez longue période, mais ne vous arrêtez pas là-bas. Ajoutez des index, changez-les, demandez si vous stockez des données que vous n'avez pas besoin de stocker et de regarder d'autres requêtes de base de données, pas seulement la requête du compte, de juger des performances. Rechercher d'autres applications et articles de blog utilisant SQLite pour un grand nombre de lignes, et voir ce qu'ils ont fait pour y remédier à celui-ci (qui peut inclure la modification de bases de données). Fondamentalement, essayez des choses - puis faites un jugement. Ne laissez pas la peur initiale vous arrêter, pensez que vous allez tomber sur le mauvais chemin. Peut-être que vous êtes, vous n'êtes peut-être pas, mais n'arrêtez pas de vous arrêter avec la requête compteur . Toute façon que vous slice, 27 millions d'enregistrements dans une table sont une tonne de merde.

Enfin, un conseil spécifique est celui-ci: Dans SQLite, ne pas diviser la base de données en plusieurs fichiers - je ne vois pas cela aider, car vous allez alors devoir faire beaucoup de requêtes supplémentaires Travaillez, puis rejoignez manuellement vos tables distinctes après que les résultats retiennent de plusieurs requêtes. Cela réinvente ce que fait la SGBB pour vous et une idée folle. Vous n'allez pas en quelque sorte comprendre un moyen de faire des jointures plus rapides que les créateurs du système RDBMS - vous perdrez certainement du temps là-bas.


2 commentaires

Pouvez-vous s'il vous plaît expliquer que voulez-vous dire par tranchant la table? Autant que je sache SQLite ne supporte intrinsèquement aucune partitionnement horizontale.


Je ne parlais pas de la base de données, c'est juste une figure de la parole. Quand je dis "Toute façon que vous SLICE [Ce problème] ..." Je veux dire "Toute façon que vous Approche Ce problème, 27 millions d'enregistrements dans une table sont beaucoup . "



1
votes

Sélectionner le nombre (*) dans SQLite sera toujours plus lent lorsque vous comparez à d'autres DMB, car il effectue une numérisation de table pour cette demande particulière. Il n'a pas de table statistique pour aider. Cela ne signifie pas que vos requêtes de l'application seront lentes. Vous devez tester vos questions pour vraiment dire ce que vous pouvez vous attendre.

Certaines directives générales: l'indexation est un must absolu, car la navigation d'un sous-ensemble de données dans un arbre binaire est beaucoup plus rapide que de traverser une table entière lorsque la taille énorme est impliquée. Pour aider à charger le temps, vous devez trier vos données pour un index unique, et si vous n'avez pas d'index unique, le plus grand index. Si vous pouvez laisser tomber les indices avant le chargement et le remettre après, ce sera plus rapide. Si ces techniques ne pouvaient pas répondre à vos paramètres de fonctionnement et de SLA, il est temps de faire une partitionnement horizontale et d'utiliser "Attacher" sur la plage de données dont vous avez besoin. SQLite peut prendre en charge jusqu'à 10 attaches. Je sais que certains disent que le partitionnement est le travail de l'outil, non des développeurs, mais lorsque vous faites face à des limites physiques, vous devez vous déplacer vos manches ou choisir un outil commercial qui le fait sous la couverture pour vous.


0 commentaires

-1
votes

Si vous avez 50 Mo ou plus DB DB directement déployé sur le côté du client, cela signifie que vous faites quelque chose de mal. Essayez de migrer au côté serveur lors de la conservation de la clé - valeur importante du client. (juste des références) Vous n'aurez pas de temps réel, mais au moins cela produira une solution appropriée. "Server Side" est une réponse à votre question, c'est-à-dire si vous déposez ou optimisez les exigences en temps réel, car c'est ce que vous avez (en fonction de votre description). Dans tous les cas. SQLite peut gérer presque n'importe quoi, mais à partir de l'expérience personnelle, essayez simplement de garder les choses simples que possible, même dans le résultat en temps réel.


1 commentaires

Une taille unique ne convient pas à tous. Il existe de nombreux scénarios où une grande base de données côté client est parfaitement raisonnable.