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

Làm cách nào để truy vấn date_part đạt được chỉ mục?

Cả hai truy vấn của bạn đều nằm trên các bảng khác nhau ( reportimpression so với reportimpressionday ), vì vậy so sánh của hai truy vấn thực sự không phải là so sánh. Bạn có ANALYZE không cả hai? Các số liệu thống kê cột khác nhau cũng có thể đóng một vai trò nào đó. Chỉ mục hoặc bảng cồng kềnh có thể khác nhau. Một phần lớn hơn của tất cả các hàng có đủ điều kiện cho tháng 2 năm 2019 không? Vv.

Một lần chụp trong bóng tối, hãy so sánh tỷ lệ phần trăm cho cả hai bảng:

SELECT tbl, round(share * 100 / total, 2) As percentage
FROM  (
   SELECT text 'reportimpression' AS tbl
        , count(*)::numeric AS total
        , count(*) FILTER (WHERE datelocal >= '2019-02-01' AND datelocal < '2019-03-01')::numeric AS share
   FROM  reportimpression

   UNION ALL
   SELECT 'reportimpressionday'
        , count(*)
        , count(*) FILTER (WHERE datelocal >= '2019-02-01' AND datelocal < '2019-03-01')
   FROM  reportimpressionday
  ) sub;

Là một cho reportimpression to hơn? Sau đó, nó có thể chỉ vượt quá con số mà một chỉ mục dự kiến ​​sẽ giúp.

Nói chung, chỉ mục của bạn reportimpression_datelocal_index trên (datelocal) có vẻ tốt cho nó và reportimpression_viewership_index thậm chí cho phép quét chỉ mục nếu autovacuum đánh bại tải ghi trên bảng. (Mặc dù số lần hiển thị & nhóm tuổi chỉ là vận chuyển hàng hóa chết cho việc này và nó sẽ hoạt động tốt hơn nếu không có).

Trả lời

Bạn nhận được 26,6 phần trăm và ngày là 26,4 phần trăm cho truy vấn của tôi. Đối với một tỷ lệ phần trăm lớn như vậy, các chỉ mục thường không hữu ích chút nào . Quét tuần tự thường là cách nhanh nhất. Chỉ quét theo chỉ mục có thể vẫn có ý nghĩa nếu bảng bên dưới lớn hơn nhiều. (Hoặc bạn bị nặng bảng cồng kềnh và các chỉ mục ít bị cồng kềnh hơn, điều này làm cho các chỉ mục trở nên hấp dẫn hơn.)

Truy vấn đầu tiên của bạn có thể vượt qua điểm giới hạn. Hãy thử thu hẹp khung thời gian cho đến khi bạn thấy các bản quét chỉ lập chỉ mục. Bạn sẽ không thấy các bản quét chỉ mục (bitmap) với hơn khoảng 5% của tất cả các hàng đủ điều kiện (phụ thuộc vào nhiều yếu tố).

Truy vấn

Nếu có thể, hãy xem xét các truy vấn được sửa đổi sau:

SELECT date_part('hour', datelocal)                AS hour
     , SUM(views) FILTER (WHERE gender = 'male')   AS male
     , SUM(views) FILTER (WHERE gender = 'female') AS female
FROM   reportimpression
WHERE  datelocal >= '2019-02-01'
AND    datelocal <  '2019-03-01' -- '2019-02-28'  -- ?
GROUP  BY 1
ORDER  BY 1;

SELECT date_trunc('day', datelocal)                AS day
     , SUM(views) FILTER (WHERE gender = 'male')   AS male
     , SUM(views) FILTER (WHERE gender = 'female') AS female
FROM   reportimpressionday
WHERE  datelocal >= '2019-02-01'
AND    datelocal <  '2019-03-01'
GROUP  BY 1
ORDER  BY 1;

Những điểm chính

  • Khi sử dụng định dạng ngày được bản địa hóa như '2-1-2019' , truy cập to_timestamp () với các chỉ định định dạng rõ ràng. Nếu không, điều này phụ thuộc vào cài đặt ngôn ngữ và có thể ngắt (âm thầm) khi được gọi từ một phiên có cài đặt khác nhau. Thay vì sử dụng các định dạng ngày / giờ ISO như đã trình bày mà không phụ thuộc vào cài đặt ngôn ngữ.

  • Có vẻ như bạn muốn bao gồm cả cả tháng Của tháng hai. Nhưng truy vấn của bạn bỏ lỡ giới hạn trên. Đối với một, tháng Hai có thể có 29 ngày. datelocal <'2-28-2019' cũng loại trừ tất cả ngày 28 tháng 2. Sử dụng datelocal <'2019-03-01' thay vào đó.

  • Sẽ rẻ hơn khi nhóm và sắp xếp theo cùng một biểu thức như bạn có trong SELECT danh sách nếu bạn có thể. Vì vậy, hãy sử dụng date_trunc () ở đó, quá. Đừng sử dụng các biểu thức khác nhau mà không cần thiết. Nếu bạn cần phần ngày tháng trong kết quả, hãy áp dụng nó trên biểu thức được nhóm, như:

    SELECT date_part('day', date_trunc('day', datelocal)) AS day
    ...
    GROUP  BY date_trunc('day', datelocal)
    ORDER  BY date_trunc('day', datelocal);
    

    Mã ồn ào hơn một chút, nhưng nhanh hơn (và có thể dễ dàng hơn để tối ưu hóa cho công cụ lập kế hoạch truy vấn).

  • Sử dụng FILTER tổng hợp mệnh đề trong Postgres 9.4 trở lên. Nó sạch hơn và nhanh hơn một chút. Xem:




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. JavaScript (Postgres DB) - Cách sử dụng một câu lệnh đã chuẩn bị sẵn với một mảng làm tham số trong mệnh đề WHERE IN ()

  2. Gây ra bởi:java.lang.NoSuchMethodError:org.postgresql.core.BaseConnection.getEncoding () Lorg / postgresql / core / Encoding;

  3. Làm thế nào để tăng kết nối tối đa trong postgres?

  4. Làm cách nào để truyền một ngày null trong một nativeQuery ở chế độ ngủ đông?

  5. Chọn từ hàm PostgreSQL trả về kiểu kết hợp