สถิติของดัชนีในพาร์ติชั่นที่ไม่ได้ใช้ในการสืบค้นบนตารางทั้งหมด


9

การเข้าร่วมต่อไปนี้มีการประมาณการแถวแตกต่างกันมากเมื่อทำการเข้าร่วมในพาร์ทิชันเทียบกับเมื่อเข้าร่วมในตารางทั้งหมด:

CREATE TABLE m_data.ga_session (
  session_id         BIGINT                   NOT NULL,
  visitor_id         BIGINT                   NOT NULL,
  transaction_id     TEXT,

  timestamp          TIMESTAMP WITH TIME ZONE NOT NULL,
  day_id             INTEGER                  NOT NULL,
  [...]

  device_category    TEXT                     NOT NULL,
  [...]
  operating_system   TEXT

);

สำหรับพาร์ติชันทั้งหมด:

CREATE TABLE IF NOT EXISTS m_data.ga_session_20170127 ( CHECK (day_id = 20170127) ) INHERITS (m_data.ga_session);
-- the identifier are theoretically invalid, but they get truncated to 63 chars and nevertheless work
CREATE INDEX IF NOT EXISTS "ga_session__m_tmp.normalize_device_category(ga_session.device_category)" on m_data.ga_session_20170127 USING btree (m_tmp.normalize_device_category(device_category)) ;
CREATE INDEX IF NOT EXISTS "ga_session__m_tmp.normalize_operating_system(operating_system)" on m_data.ga_session_20170127 USING btree (m_tmp.normalize_operating_system(operating_system)) ;
ANALYZE m_data.ga_session_20170127;

EXPLAIN analyse
SELECT * 
  FROM m_data.ga_session_20170127 ga_session
    JOIN m_dim_next.device ON 
      device.device_category_name = m_tmp.normalize_device_category(ga_session.device_category)
      AND device.operating_system_name = m_tmp.normalize_operating_system(ga_session.operating_system);

สถิติสำหรับดัชนีเหล่านี้บนพาร์ติชันสามารถมองเห็นได้:

SELECT * FROM pg_stats WHERE tablename ilike 'ga_session_20170127%';

schemaname |tablename                                                       |attname                    |inherited |null_frac   |avg_width |n_distinct   
-----------|----------------------------------------------------------------|---------------------------|----------|------------|----------|-------------
m_data     |ga_session_20170127__m_tmp.normalize_device_category(device_cat |normalize_device_category  |false     |0           |10        |3            
m_data     |ga_session_20170127__m_tmp.normalize_operating_system(operating |normalize_operating_system |false     |0           |7         |14           

นี้ (พร้อมสถิติในดัชนีบนพาร์ติชัน) ผลลัพธ์ในการประมาณการแผนแบบสอบถาม (ละเอียด) ต่อไปนี้: 80146 โดยประมาณ 77503 จริง

Hash Join  (cost=1.95..6103.53 rows=80146 width=262) (actual time=0.121..117.204 rows=77503 loops=1)
  Hash Cond: ((COALESCE(initcap(ga_session.device_category), 'Unknown'::text) = device.device_category_name) AND (COALESCE(replace(ga_session.operating_system, '(not set)'::text, 'Unknown'::text), 'Unknown'::text) = device.operating_system_name))
  ->  Seq Scan on ga_session_20170127 ga_session  (cost=0.00..2975.03 rows=77503 width=224) (actual time=0.010..9.203 rows=77503 loops=1)
  ->  Hash  (cost=1.38..1.38 rows=38 width=38) (actual time=0.064..0.064 rows=38 loops=1)
        Buckets: 1024  Batches: 1  Memory Usage: 11kB
        ->  Seq Scan on device  (cost=0.00..1.38 rows=38 width=38) (actual time=0.006..0.019 rows=38 loops=1)
Planning time: 1.460 ms
Execution time: 120.098 ms

สิ่งที่ใช้ไม่ได้คือการเข้าร่วมในตารางทั้งหมดซึ่งประมาณจำนวนแถวที่ไม่ถูกต้องทั้งหมด (832 ประมาณเทียบกับ 876237 จริง)

QUERY PLAN                                                                                                                                                                                                                                             
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Hash Join  (cost=1.95..60056.78 rows=832 width=262) (actual time=0.037..1065.778 rows=876237 loops=1)                                                                                                                                                  
  Hash Cond: ((COALESCE(initcap(ga_session.device_category), 'Unknown'::text) = device.device_category_name) AND (COALESCE(replace(ga_session.operating_system, '(not set)'::text, 'Unknown'::text), 'Unknown'::text) = device.operating_system_name)) 
  ->  Append  (cost=0.00..33759.37 rows=876238 width=225) (actual time=0.005..132.070 rows=876237 loops=1)                                                                                                                                             
        ->  Seq Scan on ga_session  (cost=0.00..0.00 rows=1 width=319) (actual time=0.000..0.000 rows=0 loops=1)                                                                                                                                       
        ->  Seq Scan on ga_session_20170125 ga_session_1  (cost=0.00..3648.38 rows=94438 width=226) (actual time=0.005..10.606 rows=94438 loops=1)                                                                                                     
        ->  Seq Scan on ga_session_20170126 ga_session_2  (cost=0.00..3185.81 rows=82581 width=225) (actual time=0.014..8.982 rows=82581 loops=1)                                                                                                      
        ->  Seq Scan on ga_session_20170127 ga_session_3  (cost=0.00..2975.03 rows=77503 width=224) (actual time=0.002..8.797 rows=77503 loops=1)                                                                                                      
        ->  Seq Scan on ga_session_20170128 ga_session_4  (cost=0.00..2936.83 rows=76083 width=225) (actual time=0.003..7.873 rows=76083 loops=1)                                                                                                      
        ->  Seq Scan on ga_session_20170129 ga_session_5  (cost=0.00..3716.18 rows=96618 width=224) (actual time=0.002..9.318 rows=96618 loops=1)                                                                                                      
        ->  Seq Scan on ga_session_20170130 ga_session_6  (cost=0.00..3833.19 rows=99619 width=224) (actual time=0.002..9.453 rows=99619 loops=1)                                                                                                      
        ->  Seq Scan on ga_session_20170131 ga_session_7  (cost=0.00..3488.79 rows=90579 width=225) (actual time=0.002..8.298 rows=90579 loops=1)                                                                                                      
        ->  Seq Scan on ga_session_20170201 ga_session_8  (cost=0.00..3615.58 rows=93958 width=224) (actual time=0.002..9.199 rows=93958 loops=1)                                                                                                      
        ->  Seq Scan on ga_session_20170202 ga_session_9  (cost=0.00..3286.56 rows=85256 width=224) (actual time=0.006..8.021 rows=85256 loops=1)                                                                                                      
        ->  Seq Scan on ga_session_20170203 ga_session_10  (cost=0.00..3073.02 rows=79602 width=225) (actual time=0.002..7.727 rows=79602 loops=1)                                                                                                     
  ->  Hash  (cost=1.38..1.38 rows=38 width=38) (actual time=0.016..0.016 rows=38 loops=1)                                                                                                                                                              
        Buckets: 1024  Batches: 1  Memory Usage: 11kB                                                                                                                                                                                                  
        ->  Seq Scan on device  (cost=0.00..1.38 rows=38 width=38) (actual time=0.002..0.004 rows=38 loops=1)                                                                                                                                          
Planning time: 1.017 ms                                                                                                                                                                                                                                
Execution time: 1090.213 ms   

จากนั้นจะส่งผลให้ตัวเลือกการเข้าร่วมที่ไม่ถูกต้อง (ลูปซ้อนกัน) เมื่อใช้การเข้าร่วมนั้นทำให้เกิดการรวมเพิ่มขึ้น (ไม่แสดงที่นี่)

จริง ๆ แล้วฉันมีการประมาณการแถวที่ไม่ถูกต้องในพาร์ทิชันเช่นกันก่อนที่ฉันจะรันANALYSEอีกครั้งบนพาร์ติชันดังนั้นดูเหมือนว่านักวางแผนคิวรีจะไม่นำสถิติตามดัชนีมาพิจารณาเมื่อใช้ตารางทั้งหมด

มีวิธีใดบ้างที่ทำให้ตัววางแผนคิวรีรวบรวมสถิติในระดับของตารางพาเรนต์หรือนำสถิติแต่ละส่วนของพาร์ติชันมาพิจารณาเมื่อสร้างแผนคิวรี


2
คำถามจะดีกว่าสำหรับฉันถ้าคุณให้ (ส่วนที่เกี่ยวข้องของ) ตารางคำจำกัดความและดัชนีที่แท้จริงของคุณ คุณใช้งานพาร์ติชั่นได้อย่างไร? ด้วยมรดก จากนั้นไม่มีสิ่งเช่น"ดัชนีที่สร้างขึ้นบนทั้งตาราง"แต่ละดัชนีสามารถขยายได้เพียงตารางเดียวเท่านั้นนั่นคือพาร์ติชันเดียว
Erwin Brandstetter

ขออภัยฉันเพิ่มข้อมูล ดัชนีอยู่ในแต่ละตาราง (ฉันสับสนเพราะเราเรียกใช้ฟังก์ชันเพื่อสร้างดัชนีในตารางที่สืบทอดทั้งหมด)
Jan Katins

คำตอบ:


1

ตรวจสอบให้แน่ใจว่าพาร์ติชั่นไม่เพียง แต่ถูกทำดัชนี แต่ยังทำตารางต้นแบบด้วยวิธีเดียวกันและ ANALYZEd

สิ่งนี้อาจทำให้ผู้วางแผนรวมการประมาณการตามดัชนีบนพาร์ติชันเดียว แต่ไม่สนใจในระดับตารางต้นแบบ

หากดัชนีนิพจน์หรือสถิติสำหรับตารางต้นแบบหายไปผู้วางแผนจะไม่สามารถสรุปการเข้าร่วมของภาวะนี้ได้แม้ว่าจะมีสถิติที่สมบูรณ์แบบสำหรับพาร์ติชันก็ตาม

เป็นเพียงการเดาเพราะคุณไม่ได้ให้สคีมาอย่างเต็มรูปแบบ โปรดแจ้งให้เราทราบหากสิ่งนี้ช่วยได้

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.