SQLite로 마이그레이션 한 800MB MS Access 데이터베이스가 있습니다. 데이터베이스의 구조는 다음과 같습니다 (마이그레이션 후 SQLite 데이터베이스는 약 330MB입니다).SQLite 쿼리가 MSAccess 쿼리보다 10 배 느리게 실행됩니다.
테이블 Occurrence
에는 1,600,000 개의 레코드가 있습니다. 그것은 다음과 같은 인덱스가
CREATE TABLE Occurrence
(
SimulationID INTEGER, SimRunID INTEGER, OccurrenceID INTEGER,
OccurrenceTypeID INTEGER, Period INTEGER, HasSucceeded BOOL,
PRIMARY KEY (SimulationID, SimRunID, OccurrenceID)
)
: 표는 모양
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)
표 OccurrenceParticipant
는 3,400,000 기록을 가지고있다. 그것은 다음과 같은 인덱스가
CREATE TABLE OccurrenceParticipant
(
SimulationID INTEGER, SimRunID INTEGER, OccurrenceID INTEGER,
RoleTypeID INTEGER, ParticipantID INTEGER
)
: 표는 모양
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)
표 InitialParticipant
(130 개) 기록을 가지고있다. 테이블의 구조는 다음 테이블 인덱스가
CREATE TABLE InitialParticipant
(
ParticipantID INTEGER PRIMARY KEY, ParticipantTypeID INTEGER,
ParticipantGroupID INTEGER
)
이다
는CREATE INDEX "initialpart_participantTypeID_idx" ON "InitialParticipant" ("ParticipantGroupID" ASC)
CREATE INDEX "initialpart_ParticipantID_idx" ON "InitialParticipant" ("ParticipantID" ASC)
표 22 개 ParticipantGroup
레코드를 갖는다. 표는 다음과 같은 인덱스가
CREATE TABLE ParticipantGroup (
ParticipantGroupID INTEGER, ParticipantGroupTypeID INTEGER,
Description varchar (50), PRIMARY KEY( ParticipantGroupID )
)
처럼 보이는 : 는 "ParticipantGroup"("ParticipantGroupID"ASC) ON INDEX "ParticipantGroup_ParticipantGroupID_idx을"CREATE
표 tmpSimArgs
18 개 기록을 가지고있다.
CREATE TABLE tmpSimArgs (SimulationID varchar, SimRunID int(10))
그리고 다음 인덱스 : 그것은 다음과 같은 구조를 가지고
CREATE INDEX tmpSimArgs_SimRunID_idx ON tmpSimArgs(SimRunID ASC)
CREATE INDEX tmpSimArgs_SimulationID_idx ON tmpSimArgs(SimulationID ASC)
표 'tmpPartArgs이'(80 개) 기록을 가지고있다.
CREATE TABLE tmpPartArgs(participantID INT)
그리고 아래의 인덱스 : 그것은 아래의 구조가
CREATE INDEX tmpPartArgs_participantID_idx ON tmpPartArgs(participantID ASC)
을 나는 여러 INNER을 포함하는 쿼리가 조인 내가 직면하고있는 문제는 쿼리의 Access 버전이 정도 걸립니다이다가 두 번째 SQLite 버전의 동일한 쿼리가 10 초 (약 10 배 느린!) 반면 Access로 다시 마이 그 레이션하는 것은 불가능하고 SQLite는 유일한 옵션입니다.
나는 데이터베이스 쿼리를 작성하는 데 익숙하지 않으므로 이러한 쿼리가 어리석은 것으로 보일 수 있으므로 잘못되었거나 꼬마 접시가있는 것에 대해서는 조언을 구하십시오.
다음과 SQLite는 쿼리가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;
(이 질의는 약 10 초 정도) :
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
Access의 쿼리가(전체 쿼리를 실행하기 위해 1 초 소요) 내가 여기서 뭘 잘못하고 있는지 모르겠다.나는 모든 색인을 가지고 있지만, 나는 나를 위해 속임수를 쓸 핵심 지표를 놓치고 있다고 생각한다. 흥미로운 것은 마이그레이션 이전에 SQLite에 대한 '연구'에서 SQLite가 Access보다 모든 측면에서 더 빠르고 작고 더 나은 것으로 나타났습니다. 하지만 질의 측면에서 액세스보다 SQLite 작업 속도가 빠르다. 나는 SQLite를 처음 접했고 분명히 많은 경험과 경험이 없으므로 배우는 영혼이 나를 도와 줄 수 있다면 많은 도움이 될 것입니다.
그 쿼리는 내 머리를 아프게합니다. 나는 왜 당신이 모든 derrived 질의 (subselects)를하고 있는지 보지 못합니다. 당신은 영어로 (SQL 대신에) 당신이 그 쿼리로부터 무엇을 돌려 주려고하는지 설명 할 수 있습니까? 질문에 쉽게 답할 수 있습니다. – JohnFx
각 하위 선택 문이 영어로하는 것을 설명 할 것입니다.이 메모 상자는 600 자까지만 가능하므로 내 질문에 대답으로 설명을 게시하고 있습니다 .. –