Tôi đã thử COUNT(*)
một bảng có 150.000 hàng có khóa Chính. Nó hoạt động khoảng 5 phút, vì vậy tôi nhận ra đây là một vấn đề về lập chỉ mục.
Trích dẫn hướng dẫn sử dụng PostgreSQL :
REINDEX tương tự như việc thả và tạo lại chỉ mục trong đó nội dung chỉ mục được xây dựng lại từ đầu. Tuy nhiên, các cân nhắc khóa là khá khác nhau. REINDEX khóa ghi nhưng không đọc bảng cha của chỉ mục. Nó cũng có một khóa độc quyền trên chỉ mục cụ thể đang được xử lý, nó sẽ chặn các lần đọc cố gắng sử dụng chỉ mục đó (...) CREATE INDEX tiếp theo khóa ghi nhưng không đọc; vì chỉ mục không có ở đó, không đọc sẽ cố gắng sử dụng nó, có nghĩa là sẽ không có chặn nhưng đọc có thể bị buộc phải quét liên tục đắt tiền.
Từ kinh nghiệm của bản thân, bạn có thể nói:
- có
REINDEXING
nguy hiểm không Nó có thể làm hại tính nhất quán dữ liệu? - Nó có thể mất rất nhiều thời gian?
- Nó có phải là một giải pháp có thể xảy ra cho kịch bản của tôi?
Cập nhật:
Giải pháp hiệu quả với chúng tôi là tạo lại cùng một chỉ mục với một tên khác, sau đó xóa chỉ mục cũ.
Việc tạo chỉ mục rất nhanh và chúng tôi đã giảm kích thước chỉ mục từ 650 MB xuống còn 8 MB. Sử dụng COUNT(*)
với between
chỉ mất 3 giây.
COUNT(*)
là lựa chọn tốt nhất:If you are using count(*), the database is free to use any column to count, which means it can pick the smallest covering index to scan (note that this is why count(*) is much better than count(some_field), as long as you don't care if null values of some_field are counted). Since indexes often fit entirely in memory, this means count(*) is often very fast.