DB의 성능을 테스트하고 있는데 SQLite가 내 쿼리에 적합한 쿼리 계획을 선택하지 않았 음을 발견했습니다.
내 스키마 :
CREATE TABLE event (
ID INTEGER PRIMARY KEY NOT NULL,
netAddr INTEGER NOT NULL,
date INTEGER NOT NULL,
value INTEGER NOT NULL);
INSERT INTO event ( netAddr, date, value )
WITH RECURSIVE cnt(x) as (
VALUES(1)
UNION ALL
SELECT x+1 FROM cnt LIMIT 1000000
) SELECT 250, x, x+1000 FROM cnt;
CREATE INDEX myIdx ON event ( netAddr, ID );
질문 :
SELECT value FROM event
WHERE netAddr = 250 AND ID > 100 AND ID < 110
ORDER BY ID DESC LIMIT 1;
너무 느리게 실행되었고 쿼리 계획을 검사했습니다 :
EXPLAIN QUERY PLAN
SELECT value FROM event
WHERE netAddr = 250 AND ID > 100 AND ID < 110
ORDER BY ID DESC LIMIT 1;
나에게 줬다
0|0|0|SEARCH TABLE event USING INDEX myIdx (netAddr=?)
SQLite는 쿼리가 원하는 방식으로 정렬되어 있어도 인덱스의 두 번째 열 사용을 거부합니다.
그런 다음 다른 색인으로 테스트했습니다 :
CREATE INDEX dateIdx ON event ( netAddr, date );
EXPLAIN QUERY PLAN
SELECT value FROM event
WHERE netAddr = 250 AND date > 100 AND date < 110
ORDER BY date DESC LIMIT 1;
나에게 줬다
0|0|0|SEARCH TABLE event USING INDEX dateIdx (netAddr=? AND date>? AND date<?)
쿼리 계획은 이제 예상대로입니다.
<올>SEARCH TABLE event USING INDEX myIdx (netAddr=? AND ID>? AND ID<?)
)
?수정 :
SELECT value FROM event WHERE id = (SELECT id FROM event WHERE netAddr = 250 AND id > 100 AND id < 110 ORDER BY id DESC LIMIT 1) LIMIT 1;
와 함께 시도
그리고
SELECT value FROM event WHERE netAddr = 250 AND ID > 100 AND ID < 110 ORDER BY netAddr DESC, ID DESC LIMIT 1;
ypercubeᵀᴹ이 제안한 것처럼-결과는 "느린"쿼리와 동일합니다.
ID 열의 이름을 다른 것으로 변경하려고했습니다. 결과는 동일합니다.
편집 2 :
SQLite 버전 3.8.2 및 3.8.8.1
-
답변 # 1
-
답변 # 2
실제로
CREATE INDEX myIdx ON event ( netAddr );
를 사용하는 것으로 나타났습니다 작동합니다.EXPLAIN QUERY PLAN SELECT value FROM event WHERE netAddr = 250 AND ID > 100 AND ID < 110 ORDER BY ID DESC LIMIT 1;
주십시오
0|0|0|SEARCH TABLE event USING INDEX myIdx (netAddr=? AND rowid>? AND rowid<?)
SQLite 문서의 어느 곳에도 쓰지 않아도 인덱스의 rowid 열은 정렬 된 상태로 유지됩니다. 따라서 인덱스
( columnXXX, rowid )
를 명시 적으로 만들 필요는 없습니다. 그것을( columnXXX )
를 만드는 것으로 충분하다
관련 자료
- java - where 절을 사용하여 Android에서 sqlite 쿼리를 실행할 때 결과가 없습니다
- python - SQLite 데이터베이스에 대한 Tkinter 쿼리
- pandas - 파이썬에서 sqlite 쿼리 결과를 CSV로 내보내는 방법이 있습니까?
- c# - Excel에서 sqlite로 쿼리를 단순화하는 방법은 무엇입니까?
- sqlite - 이 쿼리에서 LEFT JOIN이 rowid로 작동하지만 INNER JOIN이 작동하지 않는 이유는 무엇입니까?
- sql - 각 주소에 거주하는 사람의 수를 선택하는 질문은 무엇입니까?
- 정수로 SQLite를 쿼리하는 방법?
- java - SQLite DELETE 쿼리가 moveToFirst ()에서 멈춤
- javascript - SQLite 쿼리를 MongoDB 쿼리로 변환하는 방법
- SQLITE DB를 사용하여 Qt 5129에서 작동하지 않는 쿼리 업데이트 (for 루프에서 쿼리)
- java - 잘못된 순서/유형 불일치로 데이터를 삽입하는 Android SQLite
- MariaDB 104 쿼리 최적화 프로그램 잘못된 실행 계획
- mysql - localdate에 대한 Spring 데이터 쿼리가 잘못된 항목을 반환합니다마이너스 하루
- python - sqlite 쿼리 - 0 개의 결과를 반환하는 select from
- python - sqlite - like 키워드가있는 sql 쿼리에 매개 변수를 제공하는 방법
- sql - 시간 시간대의 합계 값을 가져 오는 Sqlite 쿼리
- delphi - SQLite 쿼리 결과 제한
- sql - sqlite 쿼리 문제 - 가능한 두 가지 해결책?
- android - 원시 쿼리 삽입 후 SQLite 생성 ID
- datetime - 2 행 날짜 및 시간이있는 SQLite 마지막 24 시간 쿼리
- OpenCv의 폴더에서 여러 이미지 읽기 (python)
- 파이썬 셀레늄 모든 "href"속성 가져 오기
- git commit - 자식 - 로컬 커밋 된 파일에 대한 변경을 취소하는 방법
- html - 자바 스크립트 - 클릭 후 변경 버튼 텍스트 변경
- JSP에 대한 클래스를 컴파일 할 수 없습니다
- javascript - 현재 URL에서 특정 div 만 새로 고침/새로 고침
- jquery - JavaScript로 현재 세션 값을 얻으시겠습니까?
- javascript - swiperjs에서 정지, 재생 버튼 추가
- vue.js - axios를 사용하여 서버에 이미지를 업로드하는 방법
- python - 문자열에서 특정 문자 제거
이론적으로 인덱스에서 rowid를 두 번째 열로 사용하는 것은 아무 문제가 없습니다.
실제로 현재 SQLite 버전에서는 예상대로 작동합니다.