2015-05-20 12 views
5

trên postgresl 9.0 chúng tôi có một truy vấn sql:Một truy vấn postgresql sẽ không hoàn thành

SELECT count(*) FROM lane 
WHERE not exists 
    (SELECT 1 FROM id_map 
    WHERE id_map.new_id=lane.lane_id 
    and id_map.column_name='lane_id' 
    and id_map.table_name='lane') 
and lane.lane_id is not null; 

mà thường mất một chút khoảng 1,5 giây để kết thúc. Đây là kế hoạch giải thích: http://explain.depesz.com/s/axNN

Đôi khi truy vấn này bị treo và sẽ không kết thúc. Nó có thể chạy ngay cả trong 11 giờ mà không thành công. Sau đó, nó chiếm 100% CPU.

Khóa duy nhất mà truy vấn này nhận là "AccessShareLock" và tất cả đều được cấp.

SELECT a.datname, 
     c.relname, 
     l.transactionid, 
     l.mode, 
     l.granted, 
     a.usename, 
     a.current_query, 
     a.query_start, 
     age(now(), a.query_start) AS "age", 
     a.procpid 
    FROM pg_stat_activity a 
    JOIN pg_locks   l ON l.pid = a.procpid 
    JOIN pg_class   c ON c.oid = l.relation 
    ORDER BY a.query_start; 

Các truy vấn được chạy như một phần của tiến trình java kết nối với một cơ sở dữ liệu bằng cách sử dụng hồ bơi kết nối và thực hiện chọn các truy vấn liên tục tương tự của định dạng này:

SELECT count(*) FROM {} WHERE not exists (SELECT 1 FROM id_map WHERE id_map.new_id={}.{} and id_map.column_name='{}' and id_map.table_name='{}') and {}.{} is not null 

không cập nhật hoặc xóa đang xảy ra song song với quá trình này vì vậy tôi không nghĩ rằng hút bụi có thể là vấn đề ở đây. Trước khi chạy toàn bộ quá trình (vì vậy trước khi 6 truy vấn loại này được chạy), một phân tích trên tất cả các bảng đã được chạy.

nhật ký postgres không hiển thị bất kỳ mục nhập nào cho các truy vấn chạy dài vì chúng không bao giờ kết thúc và do đó không bao giờ được đăng nhập.

Bất kỳ ý tưởng nào có thể gây ra loại hành vi này và cách ngăn chặn hành vi đó xảy ra?

các giải thích kế hoạch mà không cần phân tích:

Aggregate (cost=874337.91..874337.92 rows=1 width=0) 
    -> Nested Loop Anti Join (cost=0.00..870424.70 rows=1565283 width=0) 
     Join Filter: (id_map.new_id = lane.lane_id) 
     -> Seq Scan on lane (cost=0.00..30281.84 rows=1565284 width=8) 
       Filter: (lane_id IS NOT NULL) 
     -> Materialize (cost=0.00..816663.60 rows=1 width=8) 
       -> Seq Scan on id_map (cost=0.00..816663.60 rows=1 width=8) 
        Filter: (((column_name)::text = 'lane_id'::text) AND ((table_name)::text = 'lane'::text)) 
+0

tôi đã có cùng một vấn đề với java . Nó không phải là phiên bản postgres - nó đã được java không chấm dứt kết nối ... 100% CPU của postgres hoặc java? .. những gì có trong pg_stat_activity? .. –

+0

100% bởi postgres. pg_stat_activity hiển thị truy vấn sql không bao giờ là – norbitheeviljester

+0

khi nó chuyển sang CPU 100%, bạn có thể kiểm tra kế hoạch không? Nó có thể là các vòng lặp lồng nhau thay vì kết nối băm - điều đó có nghĩa là bạn cho quá ít RAM để lưu vào bộ đệm ... Một cách tiếp cận khác là " "Nhưng cả hai đều có giá trị nghiên cứu nếu kế hoạch thực hiện khác khi nó đạt 100% CPU –

Trả lời

5
VACUUM ANALYZE VERBOSE; 

thống kê làm mới sẽ giúp db để lựa chọn phương án tối ưu - vòng không lồng nhau, mà tôi tin rằng mất 100% CPU

+0

Tôi đã quản lý để xác minh rằng đây thực sự là nguyên nhân gốc rễ của vấn đề. Vòng lặp lồng nhau tạo ra 1,5 triệu lần quét tuần tự của bảng id_map, mất nhiều ngày để hoàn thành. Khi thực hiện phân tích chân không trên cả hai bảng trước khi chạy truy vấn, truy vấn sẽ kết thúc sau chưa đầy 2 giây. – norbitheeviljester

Các vấn đề liên quan