Tôi đang cố gắng tạo một chỉ mục trong SQLite3
(3.18) bằng các json_extract
biểu thức. Mục đích của tôi là thực hiện các truy vấn chỉ yêu cầu chỉ mục để mang lại kết quả. Lý do cho điều này là json_extract
một hoạt động đắt tiền sẽ cản trở hiệu suất khi hoạt động trên các tập dữ liệu và / hoặc giá trị lớn hơn. Tôi kết luận tôi cần một chỉ số bao phủ phù hợp với nhu cầu của tôi.
Bước 1 - Kiểm tra lý thuyết bằng cấu trúc bảng bình thường
CREATE TABLE Player (
Id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
FirstName TEXT NOT NULL,
MiddleName TEXT,
LastName TEXT NOT NULL
);
CREATE INDEX Player_FirstName ON Player (
FirstName ASC,
LastName ASC
);
EXPLAIN QUERY PLAN SELECT
FirstName, LastName
FROM
Player
WHERE
LENGTH(LastName) > 10
ORDER BY
FirstName
LIMIT
10
OFFSET
0
Sản lượng
SCAN TABLE Player USING COVERING INDEX Player_FirstName
Đây chính xác là những gì tôi mong đợi. Trình hoạch định truy vấn đã chỉ ra rằng Player_FirstName
chỉ mục phù hợp do ORDER BY
mệnh đề và vì WHERE
câu lệnh chỉ hoạt động trên một giá trị cũng nằm trong chỉ mục đó, nên không cần phải đọc bảng. Cuối cùng, SELECT
tuyên bố chỉ bao gồm các cột được đánh chỉ mục do đó dẫn đến một truy vấn mà không chạm vào bàn ở tất cả .
Bước 2 - Kiểm tra lý thuyết với biểu thức trích xuất
CREATE TABLE PlayerJ (
Id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
Data TEXT NOT NULL
);
CREATE INDEX PlayerJ_FirstName ON PlayerJ (
JSON_EXTRACT(Data, '$.FirstName') ASC,
JSON_EXTRACT(Data, '$.LastName') ASC
);
EXPLAIN QUERY PLAN SELECT
JSON_EXTRACT(Data, '$.FirstName') AS FirstName,
JSON_EXTRACT(Data, '$.LastName') AS LastName
FROM
PlayerJ
WHERE
LENGTH(LastName) > 10
ORDER BY
FirstName
LIMIT
10
OFFSET
0
Sản lượng
SCAN TABLE PlayerJ USING INDEX PlayerJ_FirstName
Đây không phải là những gì tôi mong đợi. Trình hoạch định truy vấn dường như đã tìm ra rằng ORDER BY
mệnh đề này được bật JSON_EXTRACT(Data, '$.FirstName')
và do đó dường như đã chọn chỉ mục thích hợp. Nhưng đó là nơi lý luận của tôi kết thúc đột ngột. Chuyện gì đang xảy ra ở đây? Tôi đã dự kiến trình hoạch định truy vấn sẽ chỉ ra rằng đây giống như thử nghiệm trước đó và chỉ mục sẽ được sử dụng làm chỉ mục bao trùm. Nhưng nó không.
Tại sao không? Và làm thế nào thử nghiệm thứ hai này có thể được sửa đổi để nó chỉ chạy với chỉ số?