Postgres THAM GIA điều kiện so với điều kiện WHERE


10

Postgres người mới ở đây.

Tôi đang tự hỏi nếu truy vấn này được tối ưu hóa hay không? Tôi đã cố gắng THAM GIA chỉ các giá trị cần thiết 100% và để lại tất cả các điều kiện động trong mệnh đề WHERE. Xem bên dưới.

SELECT *
    FROM
      myapp_employees
    JOIN myapp_users ON
      myapp_users.user_id=myapp_employees.user_id
    JOIN myapp_contacts_assoc ON
      myapp_contacts_assoc.user_id=myapp_users.user_id
    JOIN myapp_contacts ON
      myapp_contacts.contact_id=myapp_contacts_assoc.contact_id
    WHERE
      myapp_contacts.value='test@gmail.com' AND
      myapp_contacts.type=(1)::INT2 AND
      myapp_contacts.is_primary=(1)::INT2 AND
      myapp_contacts.expired_at IS NULL AND
      myapp_employees.status=(1)::INT2 AND
      myapp_users.status=(1)::INT2
    LIMIT 1;

Lưu ý: Đối với ngữ cảnh, Proc này đang kiểm tra xem liệu người dùng cũng là nhân viên (tư nhân nâng cao / loại người dùng khác nhau).

Dù sao, đây có phải là con đường đúng đắn? Ví dụ, THAM GIA có nên chứa nhiều câu lệnh hơn như kiểm tra expired_at IS NULL không? Tại sao hoặc tại sao điều này không có ý nghĩa?


Còn phiên bản Postgres của bạn thì sao? ( SELECT version();)
Erwin Brandstetter

@ErwinBrandstetter Tôi đang chạy PostgreSQL 9.3.14. Đây có nên là một cái gì đó mà tôi yêu cầu trong mỗi chức năng?
Dan

2
Không, chúng tôi ở đây trên dba.SE yêu cầu bạn khai báo các phiên bản phần mềm có liên quan, vì chúng tạo ra sự khác biệt cho nhiều câu hỏi.
Erwin Brandstetter

Câu trả lời:


13

Về mặt logic , nó không có sự khác biệt nào cho dù bạn đặt điều kiện trong mệnh đề nối của một INNER JOINhoặc WHEREmệnh đề giống nhau SELECT. Hiệu quả là như nhau.

(Không phải trường hợp nào OUTER JOIN!)

Trong khi hoạt động với các cài đặt mặc định, nó cũng không tạo ra sự khác biệt cho kế hoạch truy vấn hoặc hiệu suất . Postgres có thể tự do sắp xếp lại các tham gia và JOIN& WHEREđiều kiện trong nhiệm vụ của mình cho kế hoạch truy vấn tốt nhất - miễn là số lượng bảng không lớn hơn join_collapse_limit(mặc định 8). Chi tiết:

Để dễ đọc và duy trì , nên đặt các điều kiện kết nối các bảng trong JOINmệnh đề tương ứng và các điều kiện chung trong WHEREmệnh đề.

Truy vấn của bạn trông tốt Tôi sẽ sử dụng bí danh bảng để giảm tiếng ồn, mặc dù.

Chi tiết nhỏ:

int2 '1'hoặc thậm chí 1::int2là hợp lý hơn (1)::INT2. Và trong khi so sánh với một giá trị của kiểu dữ liệu số được xác định rõ, một hằng số số đơn giản 1cũng đủ tốt.


2

Một vài điểm ..

  1. Nếu bạn tham gia với một điều kiện có cùng tên ( user_id) trong trường hợp của bạn, bạn có thể sử dụng USING (user_id)chứ không phải ON (a.user_id = b.user_id). Điều này cũng lưu một cột dự phòng khỏi khả năng bị xuất ra (nếu bạn đang chạy SELECT *trong sản xuất).

  2. 1::int2có vấn đề Hoặc status, và is_primarynhững người khác đã sẵn sàng int2trong trường hợp đó, chữ 1 sẽ tự động được chuyển thành int2 hoặc int2 được chuyển thành int khi pg thấy phù hợp. Hoặc, nếu bạn lưu trữ chúng dưới dạng ints thông thường và bỏ chúng xuống như thể điều đó tạo ra sự khác biệt trong tính toán - điều đó không có, chỉ riêng diễn viên đã biến điều đó thành một đề xuất thất bại.

  3. Khi có thể, tất cả :: int2 có thể nên được lưu trữ dưới dạng boolean. Sau đó, bạn có thể viết WHEREđiều kiện của bạn để đơn giản hơn.

  4. Đối với loại và trạng thái của bạn, bạn có thể muốn một ENUMloại.

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.