Tôi gặp sự cố với các truy vấn chậm do trình lập kế hoạch kiểm tra mọi bảng được kế thừa thay vì chỉ có bảng có ràng buộc.
Tôi có một bảng có 0 hàng gọi là "search_result". Bảng này có một vài bảng được kế thừa với các ràng buộc khác nhau dựa trên "phân cực", nơi tất cả dữ liệu của chúng tôi nằm. Ví dụ:
CREATE TABLE search_result_positive
(
CONSTRAINT search_result_positive_polarization_check CHECK (polarization = (1))
)
INHERITS (search_result);
CREATE TABLE search_result_negative
(
CONSTRAINT search_result_negative_polarization_check CHECK (polarization = (-1))
)
INHERITS (search_result);
CREATE TABLE search_result_unpolarized
(
CONSTRAINT search_result_unpolarized_polarization_check CHECK (polarization IS NULL)
)
INHERITS (search_result);
Ví dụ, khi tôi thực hiện truy vấn bằng cách sử dụng "WHERE Polarization = 1", trình lập kế hoạch truy vấn sẽ hiển thị rằng nó chỉ kiểm tra bảng "search_result_poseitive": đây là hành vi mong muốn.
Tuy nhiên, khi truy vấn là "WHERE phân cực là NULL", nó sẽ kiểm tra từng bảng một, mất rất nhiều thời gian. Đây là một ví dụ cho "search_result_poseitive":
SELECT "search_result".* FROM "search_result" WHERE (polarization = 1) ORDER BY published_on DESC LIMIT 20;
Limit (cost=0.44..17.65 rows=20 width=2027) (actual time=3.638..3.666 rows=20 loops=1)
-> Merge Append (cost=0.44..249453.67 rows=289872 width=2027) (actual time=3.637..3.663 rows=20 loops=1)
Sort Key: search_result.published_on DESC
-> Sort (cost=0.01..0.02 rows=1 width=2882) (actual time=0.004..0.004 rows=0 loops=1)
Sort Key: search_result.published_on DESC
Sort Method: quicksort Memory: 25kB
-> Seq Scan on search_result (cost=0.00..0.00 rows=1 width=2882) (actual time=0.002..0.002 rows=0 loops=1)
Filter: (polarization = 1)
-> Index Scan Backward using ix_search_result_positive_published_on_asc on search_result_positive (cost=0.42..245830.25 rows=289871 width=2027) (actual time=3.633..3.658 rows=20 loops=1)
Filter: (polarization = 1)
Planning time: 2.640 ms
Execution time: 3.762 ms
Và bây giờ, đây là những gì xảy ra khi chúng tôi truy vấn null:
SELECT "search_result".* FROM "search_result" WHERE (polarization IS NULL) ORDER BY published_on DESC LIMIT 20;
Limit (cost=1.93..143.83 rows=20 width=1758) (actual time=205790.210..206266.419 rows=20 loops=1)
-> Merge Append (cost=1.93..462744.74 rows=65221 width=1758) (actual time=205790.208..206266.403 rows=20 loops=1)
Sort Key: search_result.published_on DESC
-> Sort (cost=0.01..0.02 rows=1 width=2882) (actual time=0.006..0.006 rows=0 loops=1)
Sort Key: search_result.published_on DESC
Sort Method: quicksort Memory: 25kB
-> Seq Scan on search_result (cost=0.00..0.00 rows=1 width=2882) (actual time=0.001..0.001 rows=0 loops=1)
Filter: (polarization IS NULL)
-> Index Scan using ix_search_result_hybrid_published_on_desc on search_result_hybrid (cost=0.14..44.44 rows=1 width=2882) (actual time=0.002..0.002 rows=0 loops=1)
Filter: (polarization IS NULL)
-> Index Scan Backward using ix_search_result_negative_published_on_asc on search_result_negative (cost=0.42..126163.49 rows=1 width=2039) (actual time=44646.431..44646.431 rows=0 loops=1)
Filter: (polarization IS NULL)
Rows Removed by Filter: 174428
-> Index Scan Backward using ix_search_result_neutral_published_on_asc on search_result_neutral (cost=0.42..53749.59 rows=1 width=1996) (actual time=29539.393..29539.393 rows=0 loops=1)
Filter: (polarization IS NULL)
Rows Removed by Filter: 115678
-> Index Scan using ix_search_result_no_apply_published_on_desc on search_result_no_apply (cost=0.14..44.44 rows=1 width=2882) (actual time=0.003..0.003 rows=0 loops=1)
Filter: (polarization IS NULL)
-> Index Scan Backward using ix_search_result_positive_published_on_asc on search_result_positive (cost=0.42..245105.57 rows=1 width=2027) (actual time=131590.509..131590.509 rows=0 loops=1)
Filter: (polarization IS NULL)
Rows Removed by Filter: 295475
-> Index Scan using ix_search_result_unpolarized_published_on_desc on search_result_unpolarized (cost=0.29..35643.06 rows=65215 width=1758) (actual time=13.863..490.048 rows=20 loops=1)
Filter: (polarization IS NULL)
Planning time: 1.197 ms
Execution time: 206266.593 ms
Điều này khiến tôi điên mất. Tôi không hiểu tại sao mọi bảng đang được kiểm tra thay vì chỉ "search_result_unpolarized". Điều này đang khiến tôi phát điên. Sự lựa chọn duy nhất khác mà tôi có cho việc này là viết lại một phần trong hệ thống của chúng tôi để chỉ truy vấn một bảng cụ thể thay vì để Postgres quyết định, đây sẽ là một lượng công việc khá lớn. Phải có cách tốt hơn. Bất kỳ trợ giúp hay ý tưởng sẽ được đánh giá rất nhiều.
Chúng tôi đang sử dụng Postgres 9.3.19 trên Amazon RDS
check (polarization is not null)
nhưng trước tiên bạn cần di chuyển các giá trị null ra khỏi các bảng con.