LIKE
không có ký tự đại diện tương đương với =
. Giả sử ý bạn thực sự là name = 'text'
.
Chỉ mục là chìa khóa cho hiệu suất.
Thiết lập thử nghiệm
CREATE TABLE image (
image_id serial PRIMARY KEY
, group_id int NOT NULL
, name text NOT NULL
);
Lý tưởng nhất là bạn tạo hai chỉ mục (ngoài khóa chính):
CREATE INDEX image_name_grp_idx ON image (name, group_id);
CREATE INDEX image_grp_idx ON image (group_id);
Lần thứ hai có thể không cần thiết, tùy thuộc vào phân phối dữ liệu và các chi tiết khác. Giải thích tại đây:
- Chỉ số tổng hợp có tốt cho các truy vấn trên trường đầu tiên không?
Truy vấn
Đây phải là nhanh nhất có thể truy vấn cho trường hợp của bạn:
SELECT * FROM image WHERE name = 'name105' AND group_id = 10
UNION ALL
SELECT * FROM image WHERE name = 'name105'
UNION ALL
SELECT * FROM image WHERE group_id = 10
LIMIT 1;
SQL Fiddle.
LIMIT
mệnh đề áp dụng cho toàn bộ truy vấn. Postgres đủ thông minh để không thực thi chân sau của UNION ALL
ngay sau khi tìm thấy đủ hàng để đáp ứng LIMIT
. Do đó, đối với một trận đấu ở đầu tiên SELECT
của truy vấn, đầu ra của EXPLAIN ANALYZE
trông giống như thế này ( cuộn sang bên phải! ):
Limit (cost=0.00..0.86 rows=1 width=40) (actual time=0.045..0.046 rows=1 loops=1) Buffers: local hit=4 -> Result (cost=0.00..866.59 rows=1002 width=40) (actual time=0.042..0.042 rows=1 loops=1) Buffers: local hit=4 -> Append (cost=0.00..866.59 rows=1002 width=40) (actual time=0.039..0.039 rows=1 loops=1) Buffers: local hit=4 -> Index Scan using image_name_grp_idx on image (cost=0.00..3.76 rows=2 width=40) (actual time=0.035..0.035 rows=1 loops=1) Index Cond: ((name = 'name105'::text) AND (group_id = 10)) Buffers: local hit=4 -> Index Scan using image_name_grp_idx on image (cost=0.00..406.36 rows=500 width=40) (never executed) Index Cond: (name = 'name105'::text) -> Index Scan using image_grp_idx on image (cost=0.00..406.36 rows=500 width=40) (never executed) Index Cond: (group_id = 10) Total runtime: 0.087 ms
Nhấn mạnh đậm của tôi.
Không không thêm ORDER BY
mệnh đề , điều này sẽ làm mất tác dụng. Sau đó, Postgres sẽ phải xem xét tất cả các hàng trước khi trả lại hàng trên cùng.
Câu hỏi cuối cùng
Có giải pháp chung nào cho điều đó không?
Đây là giải pháp chung. Thêm càng nhiều SELECT
tuyên bố như bạn muốn.
Tất nhiên sẽ rất hữu ích khi kết quả tìm kiếm được sắp xếp theo mức độ liên quan của nó.
Chỉ có một hàng trong kết quả có LIMIT 1
. Loại sắp xếp khoảng trống.