J'ai une base de données MS Access de 800 Mo que j'ai migrée vers SQLite. La structure de la base de données est la suivante (la base de données SQLite, après la migration, est d'environ 330 Mo):La requête SQLite s'exécute 10 fois plus lentement que la requête MSAccess
La table Occurrence
contient 1 600 000 enregistrements. Le tableau ressemble à:
CREATE TABLE Occurrence
(
SimulationID INTEGER, SimRunID INTEGER, OccurrenceID INTEGER,
OccurrenceTypeID INTEGER, Period INTEGER, HasSucceeded BOOL,
PRIMARY KEY (SimulationID, SimRunID, OccurrenceID)
)
Il a les indices suivants:
CREATE INDEX "Occurrence_HasSucceeded_idx" ON "Occurrence" ("HasSucceeded" ASC)
CREATE INDEX "Occurrence_OccurrenceID_idx" ON "Occurrence" ("OccurrenceID" ASC)
CREATE INDEX "Occurrence_SimRunID_idx" ON "Occurrence" ("SimRunID" ASC)
CREATE INDEX "Occurrence_SimulationID_idx" ON "Occurrence" ("SimulationID" ASC)
Le tableau OccurrenceParticipant
a 3.400.000 enregistrements. Le tableau ressemble à:
CREATE TABLE OccurrenceParticipant
(
SimulationID INTEGER, SimRunID INTEGER, OccurrenceID INTEGER,
RoleTypeID INTEGER, ParticipantID INTEGER
)
Il a les indices suivants:
CREATE INDEX "OccurrenceParticipant_OccurrenceID_idx" ON "OccurrenceParticipant" ("OccurrenceID" ASC)
CREATE INDEX "OccurrenceParticipant_ParticipantID_idx" ON "OccurrenceParticipant" ("ParticipantID" ASC)
CREATE INDEX "OccurrenceParticipant_RoleType_idx" ON "OccurrenceParticipant" ("RoleTypeID" ASC)
CREATE INDEX "OccurrenceParticipant_SimRunID_idx" ON "OccurrenceParticipant" ("SimRunID" ASC)
CREATE INDEX "OccurrenceParticipant_SimulationID_idx" ON "OccurrenceParticipant" ("SimulationID" ASC)
Le tableau InitialParticipant
a 130 dossiers. La structure de la table est
CREATE TABLE InitialParticipant
(
ParticipantID INTEGER PRIMARY KEY, ParticipantTypeID INTEGER,
ParticipantGroupID INTEGER
)
Le tableau présente les indices suivants:
CREATE INDEX "initialpart_participantTypeID_idx" ON "InitialParticipant" ("ParticipantGroupID" ASC)
CREATE INDEX "initialpart_ParticipantID_idx" ON "InitialParticipant" ("ParticipantID" ASC)
Le tableau ParticipantGroup
a 22 dossiers. Il semble que
CREATE TABLE ParticipantGroup (
ParticipantGroupID INTEGER, ParticipantGroupTypeID INTEGER,
Description varchar (50), PRIMARY KEY( ParticipantGroupID )
)
Le tableau a l'index suivant: CREATE INDEX "ParticipantGroup_ParticipantGroupID_idx" ON "ParticipantGroup" ("ParticipantGroupID" ASC)
Le tableau tmpSimArgs
a 18 dossiers. Il a la structure suivante:
CREATE TABLE tmpSimArgs (SimulationID varchar, SimRunID int(10))
Et les indices suivants:
CREATE INDEX tmpSimArgs_SimRunID_idx ON tmpSimArgs(SimRunID ASC)
CREATE INDEX tmpSimArgs_SimulationID_idx ON tmpSimArgs(SimulationID ASC)
Le tableau « tmpPartArgs » a 80 dossiers. Il a la structure ci-dessous:
CREATE TABLE tmpPartArgs(participantID INT)
Et l'index ci-dessous:
CREATE INDEX tmpPartArgs_participantID_idx ON tmpPartArgs(participantID ASC)
J'ai une requête qui implique plusieurs INNER JOIN et le problème que je suis confronté est la version d'accès de la requête prend environ une deuxième alors que la version SQLite de la même requête prend 10 secondes (environ 10 fois plus lent!) Il m'est impossible de revenir à Access et SQLite est ma seule option.
Je suis nouveau à écrire des requêtes de base de données, par conséquent ces requêtes peuvent sembler stupides, alors s'il vous plaît donner des conseils sur tout ce que vous voyez défectueux ou kid-plat.
La requête dans Access est (toute requête prend 1 seconde pour exécuter):
SELECT ParticipantGroup.Description, Occurrence.SimulationID, Occurrence.SimRunID, Occurrence.Period, Count(OccurrenceParticipant.ParticipantID) AS CountOfParticipantID FROM
(
ParticipantGroup INNER JOIN InitialParticipant ON ParticipantGroup.ParticipantGroupID = InitialParticipant.ParticipantGroupID
) INNER JOIN
(
tmpPartArgs INNER JOIN
(
(
tmpSimArgs INNER JOIN Occurrence ON (tmpSimArgs.SimRunID = Occurrence.SimRunID) AND (tmpSimArgs.SimulationID = Occurrence.SimulationID)
) INNER JOIN OccurrenceParticipant ON (Occurrence.OccurrenceID = OccurrenceParticipant.OccurrenceID) AND (Occurrence.SimRunID = OccurrenceParticipant.SimRunID) AND (Occurrence.SimulationID = OccurrenceParticipant.SimulationID)
) ON tmpPartArgs.participantID = OccurrenceParticipant.ParticipantID
) ON InitialParticipant.ParticipantID = OccurrenceParticipant.ParticipantID WHERE (((OccurrenceParticipant.RoleTypeID)=52 Or (OccurrenceParticipant.RoleTypeID)=49)) AND Occurrence.HasSucceeded = True GROUP BY ParticipantGroup.Description, Occurrence.SimulationID, Occurrence.SimRunID, Occurrence.Period;
La requête SQLite est la suivante (cette requête prend environ 10 secondes):
SELECT ij1.Description, ij2.occSimulationID, ij2.occSimRunID, ij2.Period, Count(ij2.occpParticipantID) AS CountOfParticipantID FROM
(
SELECT ip.ParticipantGroupID AS ipParticipantGroupID, ip.ParticipantID AS ipParticipantID, ip.ParticipantTypeID, pg.ParticipantGroupID AS pgParticipantGroupID, pg.ParticipantGroupTypeID, pg.Description FROM ParticipantGroup as pg INNER JOIN InitialParticipant AS ip ON pg.ParticipantGroupID = ip.ParticipantGroupID
) AS ij1 INNER JOIN
(
SELECT tpa.participantID AS tpaParticipantID, ij3.* FROM tmpPartArgs AS tpa INNER JOIN
(
SELECT ij4.*, occp.SimulationID as occpSimulationID, occp.SimRunID AS occpSimRunID, occp.OccurrenceID AS occpOccurrenceID, occp.ParticipantID AS occpParticipantID, occp.RoleTypeID FROM
(
SELECT tsa.SimulationID AS tsaSimulationID, tsa.SimRunID AS tsaSimRunID, occ.SimulationID AS occSimulationID, occ.SimRunID AS occSimRunID, occ.OccurrenceID AS occOccurrenceID, occ.OccurrenceTypeID, occ.Period, occ.HasSucceeded FROM tmpSimArgs AS tsa INNER JOIN Occurrence AS occ ON (tsa.SimRunID = occ.SimRunID) AND (tsa.SimulationID = occ.SimulationID)
) AS ij4 INNER JOIN OccurrenceParticipant AS occp ON (occOccurrenceID = occpOccurrenceID) AND (occSimRunID = occpSimRunID) AND (occSimulationID = occpSimulationID)
) AS ij3 ON tpa.participantID = ij3.occpParticipantID
) AS ij2 ON ij1.ipParticipantID = ij2.occpParticipantID WHERE (((ij2.RoleTypeID)=52 Or (ij2.RoleTypeID)=49)) AND ij2.HasSucceeded = 1 GROUP BY ij1.Description, ij2.occSimulationID, ij2.occSimRunID, ij2.Period;
I Je ne sais pas ce que je fais mal ici.J'ai tous les index mais je pense que je suis absent en déclarant un index clé qui fera l'affaire pour moi. La chose intéressante est que, avant la migration, ma «recherche» sur SQLite a montré que SQLite est plus rapide, plus petit et meilleur dans tous les aspects que Access. Mais je ne peux pas sembler que SQLite fonctionne plus vite qu'Access en terme d'interrogation. Je réitère que je suis nouveau à SQLite et évidemment n'ai pas beaucoup d'idée aussi bien que l'expérience ainsi si n'importe quelle âme savante pourrait m'aider avec ceci, elle sera très appréciée.
Cette requête me fait mal à la tête. Je ne vois pas pourquoi vous faites toutes les requêtes dérivées (sous-sélections). Pouvez-vous expliquer en anglais (au lieu de SQL) ce que vous essayez de renvoyer de la requête? Cela faciliterait la réponse à votre question. – JohnFx
Je vais vous expliquer ce que fait chaque déclaration de sous-sélection en anglais .. Puisque cette boîte de commentaire ne peut contenir que 600 caractères, je poste les explications comme réponse à ma question .. –