PostgreSQL
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> PostgreSQL

Làm cách nào để thử nhiều lần CHỌN cho đến khi có kết quả?

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 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.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Nhiều SQL hơn, ít mã hơn, với PostgreSQL

  2. Để bỏ qua các khóa trùng lặp trong quá trình 'sao chép từ' trong postgresql

  3. RoR:Không thể change_column trong postgres, tốt trong MySQL (MySQL để phát triển, Postgres trên Heroku)

  4. Thay đổi ngôn ngữ của hệ thống và thông báo lỗi trong PostgreSQL

  5. Có cái gì đó giống như một hàm zip () trong PostgreSQL kết hợp hai mảng không?