ฉันใช้ PostgresSQL 9.2 และมีความสัมพันธ์ 12 คอลัมน์มีประมาณ 6,700,000 แถว มันมีโหนดในพื้นที่ 3 มิติแต่ละคนอ้างอิงผู้ใช้ (ผู้สร้างมัน) ในการสอบถามผู้ใช้รายใดที่สร้างจำนวนโหนดที่ฉันทำต่อไปนี้ (เพิ่มexplain analyze
สำหรับข้อมูลเพิ่มเติม):
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
อย่างที่คุณเห็นสิ่งนี้ใช้เวลาประมาณ 1.7 วินาที สิ่งนี้ไม่ได้เลวร้ายนักเมื่อพิจารณาจำนวนข้อมูล แต่ฉันสงสัยว่าจะสามารถปรับปรุงได้หรือไม่ ฉันพยายามเพิ่มดัชนี BTree ในคอลัมน์ผู้ใช้ แต่สิ่งนี้ไม่ได้ช่วย แต่อย่างใด
คุณมีคำแนะนำอื่นหรือไม่?
เพื่อความสมบูรณ์นี่คือคำจำกัดความของตารางที่สมบูรณ์พร้อมด้วยดัชนีทั้งหมดของมัน (โดยไม่มีข้อ จำกัด foreign key การอ้างอิงและทริกเกอร์):
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)
แก้ไข:นี่คือผลลัพธ์เมื่อฉันใช้คิวรี (และดัชนี) ที่เสนอโดย @ypercube (เคียวรีใช้เวลาประมาณ 5.3 วินาทีโดยไม่มี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
แก้ไข 2:นี่คือผลลัพธ์เมื่อฉันใช้การindex
เปิดproject_id, user_id
(แต่ยังไม่มีการเพิ่มประสิทธิภาพของ schema) ตามที่ @ erwin-brandstetter แนะนำ (แบบสอบถามทำงานด้วย 1.5 วินาทีที่ความเร็วเดียวกับแบบสอบถามดั้งเดิมของฉัน):
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
และuser_id
? มีการอัปเดตตารางอย่างต่อเนื่องหรือคุณสามารถทำงานกับมุมมองที่ปรากฏ (บางครั้ง) ได้หรือไม่
Users
ใช้user_id
เป็นคีย์หลักหรือไม่