이미지 업로드 및 태그 지정을 수행 할 수있는 이미지 업로드 서비스를 구현했습니다. 이건 내 스키마입니다 :임시 B 트리 제거 SQLite 쿼리에서 정렬
CREATE TABLE Tag(
orm_id INTEGER PRIMARY KEY AUTOINCREMENT,
pid_high UNSIGNED BIG INT NOT NULL,
pid_low UNSIGNED BIG INT NOT NULL,
name STRING NOT NULL,
CONSTRAINT KeyConstraint UNIQUE (pid_high, pid_low) ON CONFLICT FAIL);
CREATE TABLE TagBridge(
orm_id INTEGER PRIMARY KEY AUTOINCREMENT,
pid_high UNSIGNED BIG INT NOT NULL,
pid_low UNSIGNED BIG INT NOT NULL,
image_id_high UNSIGNED BIG INT NOT NULL,
image_id_low UNSIGNED BIG INT NOT NULL,
tag_id_high UNSIGNED BIG INT NOT NULL,
tag_id_low UNSIGNED BIG INT NOT NULL,
CONSTRAINT KeyConstraint UNIQUE (pid_high, pid_low) ON CONFLICT FAIL);
CREATE TABLE Image(
orm_id INTEGER PRIMARY KEY AUTOINCREMENT,
pid_high UNSIGNED BIG INT NOT NULL,
pid_low UNSIGNED BIG INT NOT NULL,
filehash STRING NOT NULL,
mime STRING NOT NULL,
uploadedDate INTEGER NOT NULL,
ratingsAverage REAL,
CONSTRAINT KeyConstraint UNIQUE (pid_high, pid_low) ON CONFLICT FAIL);
그리고 지수
CREATE INDEX ImageTest on Image(pid_high, pid_low, uploadedDate DESC);
CREATE INDEX ImagefilehashIndex ON Image (filehash);
CREATE INDEX ImageuploadedDateIndex ON Image (uploadedDate);
CREATE INDEX TagnameIndex ON Tag (name);
이유는,이 서비스는 클라이언트 권한을 128 비트 GUID를 사용하기 때문에 대신 표준 기본 키의 pid_high/pid_low 필드가 있다는 것을하지만, 이 쿼리 속도를 크게 영향을주지 않습니다.
인터넷이므로이 서비스에있는 대부분의 이미지는 고양이이며 '고양이'라는 태그가 지정되어 있습니다. 사실 50,000 개 이미지 중 약 47,000 개가 '고양이'라는 태그가 지정되어 있습니다. '고양이'태그 모든 이미지를 얻을 수있는 쿼리는 여기에 가장 큰 문제는 주문에 대한 마지막 행, 사용의 TEMP의 B-TREE입니다 이것에 대한 쿼리 계획이
sele order from deta
---- ------------- ---- ----
0 0 0 SEARCH TABLE Tag AS t USING INDEX TagnameIndex (name=?) (~1 rows)
0 1 1 SCAN TABLE TagBridge AS b (~472 rows)
0 2 2 SEARCH TABLE Image AS i USING INDEX ImageTest (pid_high=? AND pid_low=?) (~1 rows)
0 0 0 USE TEMP B-TREE FOR ORDER BY
입니다
select i.* from Tag t, TagBridge b, Image i
where
b.tag_id_high = t.pid_high AND b.tag_id_low = t.pid_low
AND b.image_id_high = i.pid_high and b.image_id_low = i.pid_low
AND t.name ='cat'
order by uploadedDate DESC LIMIT 20;
입니다 으로. 이렇게하면 쿼리 속도가 크게 느려집니다. 'order by'절이 없으면 전체 쿼리를 실행하는 데 약 0.001 초가 걸립니다. order by 절을 사용하면 쿼리에 0.483 초가 걸리고 400 배의 성능 저하가 발생합니다.
이 쿼리를 0.1 초 미만으로 얻고 싶습니다. 그러나 확실하지 않습니다. 나는 다른 많은 쿼리를 시도하고 인덱스를 추가 및 제거했지만 이것이 내가 실행할 수있는 가장 빠른 것입니다.
... '고양이'라는 질문에 대한 충동에 저항하지 않습니다. 진지하게, 질문에 좋은 일, 아주 자세하게. – bernie
아무데도 가지 않았기 때문에 내 대답을 삭제했습니다. 만약 당신이 그것을 해결할 방법을 찾으면 여기에 게시하고 @mention 나를 볼 수 있도록 기뻐할 것입니다. – Tomalak
@Tomalak : 여기에 답이 있습니다. – Quassnoi