Chỉ số và hiệu suất nhiều lớp


31

Tôi có một bảng với chỉ mục nhiều màu và tôi nghi ngờ về việc sắp xếp đúng các chỉ mục để có được hiệu suất tối đa cho các truy vấn.

Kịch bản:

  • PostgreQuery 8.4, bảng có khoảng một triệu hàng

  • Các giá trị trong cột c1 có thể có khoảng 100 giá trị khác nhau . Chúng ta có thể giả sử các giá trị được phân phối đồng đều, vì vậy chúng ta có khoảng 10000 hàng cho mỗi giá trị có thể.

  • Cột c2 có thể có 1000 giá trị khác nhau . Chúng tôi có 1000 hàng cho mỗi giá trị có thể.

Khi tìm kiếm dữ liệu, điều kiện luôn bao gồm các giá trị cho hai cột này, do đó bảng có chỉ mục nhiều màu kết hợp giữa c1 và c2. Tôi đã đọc về tầm quan trọng của việc sắp xếp đúng các cột trong chỉ mục nhiều màu nếu bạn có truy vấn chỉ sử dụng một cột để lọc. Đây không phải là trường hợp trong kịch bản của chúng tôi.

Câu hỏi của tôi là cái này:

Với thực tế là một trong các bộ lọc chọn một bộ dữ liệu nhỏ hơn nhiều, tôi có thể cải thiện hiệu suất nếu chỉ mục đầu tiên là chỉ số được chọn nhiều nhất (bộ lọc cho phép tập nhỏ hơn) không? Tôi chưa bao giờ xem xét câu hỏi này cho đến khi tôi thấy đồ họa từ bài viết được tham khảo:

nhập mô tả hình ảnh ở đây

Hình ảnh được lấy từ bài viết được tham khảo về các chỉ số nhiều màu .

Các truy vấn sử dụng các giá trị từ hai cột để lọc. Tôi không có truy vấn chỉ sử dụng một cột để lọc. Tất cả chúng là : WHERE c1=@ParameterA AND c2=@ParameterB. Cũng có những điều kiện như thế này:WHERE c1 = "abc" AND c2 LIKE "ab%"

Câu trả lời:


36

Câu trả lời

Vì bạn tham khảo trang web use-the-index-luke.com, hãy xem xét chương:

Sử dụng Chỉ mục, Luke chọn Nơi mà Tìm kiếm Tìm kiếm Phạm vi Cách tốt hơn, ít hơn và GIỮA

Nó có một ví dụ phù hợp hoàn hảo với tình huống của bạn (chỉ số hai cột, một cột được kiểm tra tính bằng nhau , cột kia cho phạm vi ), giải thích (với nhiều đồ họa chỉ số đẹp hơn) tại sao lời khuyên của @ ypercube là chính xác và tổng hợp:

Rule of thumb: index for equality first  then for ranges.

Cũng tốt cho chỉ một cột?

Phải làm gì cho các truy vấn trên chỉ một cột dường như là rõ ràng. Thêm chi tiết và điểm chuẩn liên quan đến điều đó theo các câu hỏi liên quan sau:

Cột chọn ít trước?

Ngoài ra, nếu bạn chỉ có điều kiện bình đẳng cho cả hai cột thì sao?

Nó không thành vấn đề . Đặt cột đầu tiên có nhiều khả năng nhận các điều kiện của riêng nó, điều thực sự quan trọng.

Xem xét bản demo này, hoặc tự tái tạo nó. Tôi tạo một bảng đơn giản gồm hai cột với 100k hàng. Một cái có rất ít , cái còn lại có rất nhiều giá trị riêng biệt:

CREATE TEMP TABLE t AS
SELECT (random() * 10000)::int AS lots
     , (random() * 4)::int     AS few
FROM generate_series (1, 100000);

DELETE FROM t WHERE random() > 0.9;  -- create some dead tuples, more "real-life"

ANALYZE t;

SELECT count(distinct lots)   -- 9999
     , count(distinct few)    --    5
FROM   t;

Truy vấn:

SELECT *
FROM   t
WHERE  lots = 2345
AND    few = 2;

EXPLAIN ANALYZE đầu ra (Tốt nhất trong 10 để loại trừ hiệu ứng bộ đệm):

Quét Seq trên t (chi phí = 0,00..5840,84 hàng = 2 chiều rộng = 8)
               (thời gian thực tế = 5.646..15.535 hàng = 2 vòng = 1)
  Bộ lọc: ((lot = 2345) VÀ (vài = 2))
  Bộ đệm: hit cục bộ = 443
Tổng thời gian chạy: 15,557 ms

Thêm chỉ mục, kiểm tra lại:

CREATE INDEX t_lf_idx ON t(lots, few);
Quét chỉ mục bằng cách sử dụng t_lf_idx trên t (chi phí = 0,00..3.76 hàng = 2 width = 8)
                                (thời gian thực tế = 0,008..0.011 hàng = 2 vòng = 1)
  Chỉ số Cond: ((lot = 2345) VÀ (vài = 2))
  Bộ đệm: hit cục bộ = 4
Tổng thời gian chạy: 0,027 ms

Thêm chỉ mục khác, kiểm tra lại:

DROP INDEX t_lf_idx;
CREATE INDEX t_fl_idx  ON t(few, lots);
Quét chỉ mục bằng cách sử dụng t_fl_idx trên t (chi phí = 0,00..3.74 hàng = 2 width = 8)
                                (thời gian thực tế = 0,007..0.011 hàng = 2 vòng = 1)
  Chỉ số Cond: ((few = 2) AND (lot = 2345))
  Bộ đệm: hit cục bộ = 4
Tổng thời gian chạy: 0,027 ms

Đây cũng là trường hợp cho 3 (hoặc nhiều) cột trong chỉ mục?
hayd

@hayd: Không chắc chắn "cái này" đề cập đến điều gì. Bạn có thể hỏi một câu hỏi mới . Bạn luôn có thể tham khảo cái này cho bối cảnh. (Và gửi bình luận ở đây để liên kết lại.)
Erwin Brandstetter

"Điều này" ý tôi là "việc đặt hàng của định nghĩa chỉ mục có vấn đề nếu có nhiều hơn 2 cột trong định nghĩa chỉ mục"
hayd

@hayd: Điểm quan trọng nhất: chỉ số btree phù hợp với các truy vấn có điều kiện bình đẳng trên các biểu thức chỉ mục hàng đầu . Thứ tự trong số đó hầu hết là không liên quan. Nhiều chi tiết khác sẽ không phù hợp trong một bình luận ...
Erwin Brandstetter

Cảm ơn, tôi sẽ cố gắng và viết một câu hỏi mạch lạc và liên kết với nó.
hayd

11

Nếu, như bạn nói, các truy vấn liên quan đến 2 cột này, đều là kiểm tra tính bằng nhau của cả hai cột, ví dụ:

WHERE c1=@ParameterA AND c2=@ParameterB

đừng bận tâm với điều này Tôi nghi ngờ sẽ có bất kỳ sự khác biệt và nếu có một, nó sẽ không đáng kể. Tất nhiên, bạn luôn có thể kiểm tra dữ liệu và cài đặt máy chủ của mình. Các phiên bản khác nhau của DBMS có thể hoạt động hơi khác nhau về tối ưu hóa.

Thứ tự bên trong chỉ mục sẽ quan trọng đối với các loại truy vấn khác, chỉ kiểm tra một cột hoặc điều kiện bất bình đẳng hoặc điều kiện trên một cột và nhóm trong cột khác, v.v.

Nếu tôi chọn một trong hai đơn hàng, tôi sẽ chọn đặt cột ít chọn hơn trước. Hãy xem xét một bảng với các cột yearmonth. Có nhiều khả năng bạn cần một WHERE year = 2000điều kiện hoặc a WHERE year BETWEEN 2000 AND 2013hoặc a WHERE (year, month) BETWEEN (1999, 6) AND (2000, 5).

Một truy vấn thuộc loại WHERE month = 7 GROUP BY yearcó thể muốn chắc chắn (Tìm người sinh vào tháng 7), nhưng sẽ ít thường xuyên hơn. Tất nhiên điều đó phụ thuộc vào dữ liệu thực tế được lưu trữ trong bảng của bạn. Chọn một đơn hàng ngay bây giờ, giả sử (c1, c2)và bạn luôn có thể thêm chỉ mục khác sau (c2, c1).


Cập nhật, sau bình luận của OP:

Cũng có những điều kiện như thế này: WHERE c1 = 'abc' AND c2 LIKE 'ab%'

Loại truy vấn này nếu chính xác là một điều kiện phạm vi trên c2cột và sẽ cần một (c1, c2)chỉ mục. Nếu bạn cũng có truy vấn của loại ngược lại:

WHERE c2 = 'abc' AND c1 LIKE 'ab%'

sau đó sẽ là tốt nếu bạn có một (c2, c1)chỉ số là tốt.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.