Tôi đang chạy PostgresSQL 9.2 và có quan hệ 12 cột với khoảng 6.700.000 hàng. Nó chứa các nút trong một không gian 3D, mỗi nút tham chiếu một người dùng (người đã tạo ra nó). Để truy vấn người dùng nào đã tạo bao nhiêu nút tôi làm như sau (được thêm vào explain analyze
để biết thêm thông tin):
EXPLAIN ANALYZE SELECT user_id, count(user_id) FROM treenode WHERE project_id=1 GROUP BY user_id;
QUERY PLAN
---------------------------------------------------------------------------------------------------------------------------
HashAggregate (cost=253668.70..253669.07 rows=37 width=8) (actual time=1747.620..1747.623 rows=38 loops=1)
-> Seq Scan on treenode (cost=0.00..220278.79 rows=6677983 width=8) (actual time=0.019..886.803 rows=6677983 loops=1)
Filter: (project_id = 1)
Total runtime: 1747.653 ms
Như bạn có thể thấy, điều này mất khoảng 1,7 giây. Điều này không quá tệ khi xem xét lượng dữ liệu, nhưng tôi tự hỏi liệu điều này có thể được cải thiện. Tôi đã cố gắng thêm chỉ mục BTree trên cột người dùng, nhưng điều này không giúp được gì.
Bạn có đề xuất thay thế?
Để hoàn thiện, đây là định nghĩa bảng hoàn chỉnh với tất cả các chỉ mục của nó (không có ràng buộc, tham chiếu và kích hoạt khóa ngoài):
Column | Type | Modifiers
---------------+--------------------------+------------------------------------------------------
id | bigint | not null default nextval('concept_id_seq'::regclass)
user_id | bigint | not null
creation_time | timestamp with time zone | not null default now()
edition_time | timestamp with time zone | not null default now()
project_id | bigint | not null
location | double3d | not null
reviewer_id | integer | not null default (-1)
review_time | timestamp with time zone |
editor_id | integer |
parent_id | bigint |
radius | double precision | not null default 0
confidence | integer | not null default 5
skeleton_id | bigint |
Indexes:
"treenode_pkey" PRIMARY KEY, btree (id)
"treenode_id_key" UNIQUE CONSTRAINT, btree (id)
"skeleton_id_treenode_index" btree (skeleton_id)
"treenode_editor_index" btree (editor_id)
"treenode_location_x_index" btree (((location).x))
"treenode_location_y_index" btree (((location).y))
"treenode_location_z_index" btree (((location).z))
"treenode_parent_id" btree (parent_id)
"treenode_user_index" btree (user_id)
Chỉnh sửa: Đây là kết quả, khi tôi sử dụng truy vấn (và chỉ mục) được đề xuất bởi @ypercube (truy vấn mất khoảng 5,3 giây mà không có EXPLAIN ANALYZE
):
EXPLAIN ANALYZE SELECT u.id, ( SELECT COUNT(*) FROM treenode AS t WHERE t.project_id=1 AND t.user_id = u.id ) AS number_of_nodes FROM auth_user As u;
QUERY PLAN
----------------------------------------------------------------------------------------------------------------------------------------------------------
Seq Scan on auth_user u (cost=0.00..6987937.85 rows=46 width=4) (actual time=29.934..5556.147 rows=46 loops=1)
SubPlan 1
-> Aggregate (cost=151911.65..151911.66 rows=1 width=0) (actual time=120.780..120.780 rows=1 loops=46)
-> Bitmap Heap Scan on treenode t (cost=4634.41..151460.44 rows=180486 width=0) (actual time=13.785..114.021 rows=145174 loops=46)
Recheck Cond: ((project_id = 1) AND (user_id = u.id))
Rows Removed by Index Recheck: 461076
-> Bitmap Index Scan on treenode_user_index (cost=0.00..4589.29 rows=180486 width=0) (actual time=13.082..13.082 rows=145174 loops=46)
Index Cond: ((project_id = 1) AND (user_id = u.id))
Total runtime: 5556.190 ms
(9 rows)
Time: 5556.804 ms
Chỉnh sửa 2: Đây là kết quả, khi tôi sử dụng index
bật project_id, user_id
(nhưng chưa tối ưu hóa lược đồ) như @ erwin-brandstetter đã đề xuất (truy vấn chạy với 1,5 giây với cùng tốc độ với truy vấn ban đầu của tôi):
EXPLAIN ANALYZE SELECT user_id, count(user_id) as ct FROM treenode WHERE project_id=1 GROUP BY user_id;
QUERY PLAN
---------------------------------------------------------------------------------------------------------------------------
HashAggregate (cost=253670.88..253671.24 rows=37 width=8) (actual time=1807.334..1807.339 rows=38 loops=1)
-> Seq Scan on treenode (cost=0.00..220280.62 rows=6678050 width=8) (actual time=0.183..893.491 rows=6678050 loops=1)
Filter: (project_id = 1)
Total runtime: 1807.368 ms
(4 rows)
project_id
và user_id
? Bảng có được cập nhật liên tục hay bạn có thể làm việc với chế độ xem cụ thể hóa (trong một thời gian)?
Users
vớiuser_id
khóa chính?