Si vous avez une requête telle que:
select a.Name, a.Description from a inner join b on a.id1 = b.id1 inner join c on b.id2 = c.id2 group by a.Name, a.Description
5 Réponses :
Méfiez-vous: Je ne connais rien de complexes possibles de SQLite et de ses plans d'exécution. P>
Vous avez certainement besoin d'index sur a.id1 code>,
b.id1 code>,
b.id2 code> et
c.Id2 code >. Je pense qu'un indice composite
(b.id1, b.id2) code> pourrait générer une augmentation de la performance. Il en va de même pour
(a.id1, a.name, a.description) code>. P>
à partir du Vue d'ensemble de l'optimisation de la requête SQLite : P>
Lorsque vous faites une recherche indexée d'une ligne, la procédure habituelle consiste à effectuer une recherche binaire sur l'index pour rechercher l'entrée d'index, puis extraire le Rowid de l'index et utiliser ce Rowid pour effectuer une recherche binaire sur la table d'origine. Ainsi, une recherche indexée typique implique deux recherches binaires. Si, toutefois, toutes les colonnes qui devaient être récupérées de la table sont déjà disponibles dans l'index lui-même, SQLite utilisera les valeurs contenues dans l'index et ne recherchera jamais la rangée de table d'origine. Cela permet d'économiser une recherche binaire de chaque ligne et peut rendre de nombreuses requêtes exécuter deux fois plus vite. Em> p>
Pour tout autre SGBDM, je dirais de mettre un index en cluster sur B.ID1 et C.ID2. Pour SQLite, vous risquez peut-être mieux, y compris toutes les colonnes de B et C que vous souhaitez aussi rechercher dans ces index. P>
Les index de recouvrement existent dans presque tous les SGBDM et ont le même effet sur les recherches. Le problème est que les grands indices ont blessé les performances d'insertion / mise à jour, et vous devez donc vous jongler au compromis entre les performances de mise à jour et sélectionner la performance.
Merci pour la réponse, veuillez excuser mon ignorance ici, mais vous dites que c'est possible dans SQLite de créer un index comprenant des colonnes à partir de plusieurs tables, semblables à une vue indexée dans SQLServer?
Eh bien Non, je disais que lorsque vous créez un index sur B, ne créez pas simplement l'index sur B.ID, mais également à toutes les colonnes de données dont vous avez besoin de B dans l'index. Cela vous permettra d'économiser une recherche binaire de ces colonnes de données. Dans un autre SGBD, vous pourriez probablement être encore plus rapide en incluant des colonnes à partir de plusieurs tables dans un index, mais SQLite n'est pas aussi avancée.
Le problème est que vous attendez que SQLite ait les mêmes caractéristiques de performance qu'un SGDBD complet. Ce ne sera pas. SQLLITE n'a pas le luxe de la mise en cache tout autant en mémoire, doit reconstruire la cache chaque fois que vous exécutez l'application, est probablement limitée au nombre de cœurs, etc., etc., etc., etc. Des compromis pour l'utilisation de SDBMS intégrés sur un complet. p>
En ce qui concerne les optimisations, essayez d'indexer les colonnes de recherche et le test. Ensuite, essayez de créer un index de couverture. Assurez-vous de tester les deux Sélectionnez CODE> et des chemins de code qui mettent à jour la base de données, vous accélérez l'un au détriment de l'autre. Trouvez l'indexation qui donne le meilleur équilibre entre les deux pour vos besoins et accédez à cela. P>
Merci pour la réponse, j'ai déjà tenté d'ajouter un indice composite précédemment sur A.ID1, A.Name, A.Description et un composite sur B.ID1, B.ID2 et un autre index sur C.ID2. Cependant, aucun de ceux-ci n'a contribué à la performance du groupe par. C'est une sorte que ce qui a incité la question qui semble impossible, il semble impossible d'expulser suffisamment de groupe par performance dans cette situation avec SQLite. Je suppose que ce n'est que l'une des limitations d'avoir une base de données intégrée.
Étant donné que vous n'utilisez pas les autres tables de vos colonnes de retour, cela sera peut-être plus rapide:
SELECT a.Name, a.Description FROM a WHERE a.id1 IN ( SELECT DISTINCT a.id1 FROM a WHERE a.id1 IN ( SELECT b.id1 FROM b WHERE b.id2 IN ( SELECT c.id2 FROM c ) ) )
Je pense que les index sur A.ID1 et B.ID2 vous donneraient autant de bénéfices que vous pourriez obtenir en termes de jointures. Mais SQLite propose d'expliquer et cela pourrait vous aider à déterminer s'il y a une efficacité évitable dans le plan d'exécution en cours. P>
Mon psychopathe intérieur est contrecœur au fait que vous avez un groupe par clause sans aucune fonction agrégée. Qu'essayez-vous de réaliser avec le groupe?
@Myotherme: Voir ma réponse ci-dessous, je pense qu'il veut une distincte de toutes les descriptions et noms référencés dans les tables B et C.