Postgresql 为什么同一查询(在主/复制服务器上)会得到不同的查询计划

Postgresql 为什么同一查询(在主/复制服务器上)会得到不同的查询计划,postgresql,postgresql-performance,Postgresql,Postgresql Performance,我在主服务器和复制服务器上运行相同的查询 postgresql.conf中两台服务器上的设置相同,但是主/写服务器有32GB的RAM,而复制/读服务器有16GB的RAM 以下是查询: EXPLAIN ANALYZE SELECT m.sale_date,b.branch_name, m.transaction_type, TRIM(both ' ' from UPPER(l.master_code)) as stockcode, (l.selling_pri

我在主服务器和复制服务器上运行相同的查询

postgresql.conf中两台服务器上的设置相同,但是主/写服务器有32GB的RAM,而复制/读服务器有16GB的RAM

以下是查询:

EXPLAIN ANALYZE
SELECT 
    m.sale_date,b.branch_name,
    m.transaction_type,
    TRIM(both ' '  from UPPER(l.master_code)) as stockcode, 
    (l.selling_price * l.quantity) * (1 + l.tax_percentage /100) as selling_price,l.quantity 
FROM 
    transaction_master m 
LEFT OUTER JOIN 
    transaction_line_items l ON m.guid = l.link_guid 
INNER JOIN 
    branch_details b ON m.branch_code = b.branch_code 
WHERE 
    m.sale_date BETWEEN '2015-12-22' AND '2015-12-22' 
AND 
    (m.transaction_type = 'POSSALE' OR m.transaction_type = 'POSCN' OR         m.transaction_type = 'POSREF') 
ORDER BY 
    sale_date DESC nulls LAST
在写服务器上,总时间为14秒:

Sort  (cost=1625242.60..1625417.63 rows=70012 width=50) (actual time=14732.852..14734.362 rows=72522 loops=1)
  Sort Key: m.sale_date
  Sort Method: quicksort  Memory: 11496kB
  ->  Hash Right Join  (cost=90258.98..1619608.28 rows=70012 width=50) (actual time=11202.434..14710.938 rows=72522 loops=1)
        Hash Cond: ((l.link_guid)::text = (m.guid)::text)
        ->  Seq Scan on transaction_line_items l  (cost=0.00..1258955.88 rows=23879388 width=62) (actual time=0.050..6612.397 rows=25147461 loops=1)
        ->  Hash  (cost=89903.39..89903.39 rows=28447 width=62) (actual time=46.941..46.941 rows=42504 loops=1)
              Buckets: 4096  Batches: 1  Memory Usage: 3948kB
              ->  Hash Join  (cost=4088.79..89903.39 rows=28447 width=62) (actual time=12.460..37.283 rows=42504 loops=1)
                    Hash Cond: ((m.branch_code)::text = (b.branch_code)::text)
                    ->  Bitmap Heap Scan on transaction_master m  (cost=4057.12..89480.57 rows=28447 width=52) (actual time=12.240..21.802 rows=42504 loops=1)
                          Recheck Cond: (((sale_date >= '2015-12-22'::date) AND (sale_date <= '2015-12-22'::date) AND ((transaction_type)::text = 'POSSALE'::text)) OR ((sale_date >= '2015-12-22'::date) AND (sale_date <= '2015-12-22'::date) AND ((transaction_type)::text = 'POSCN'::text)) OR ((sale_date >= '2015-12-22'::date) AND (sale_date <= '2015-12-22'::date) AND ((transaction_type)::text = 'POSREF'::text)))
                          Heap Blocks: exact=1095
                          ->  BitmapOr  (cost=4057.12..4057.12 rows=29508 width=0) (actual time=12.112..12.112 rows=0 loops=1)
                                ->  Bitmap Index Scan on tm_datebranchtype  (cost=0.00..1345.26 rows=28130 width=0) (actual time=6.013..6.013 rows=40615 loops=1)
                                      Index Cond: ((sale_date >= '2015-12-22'::date) AND (sale_date <= '2015-12-22'::date) AND ((transaction_type)::text = 'POSSALE'::text))
                                ->  Bitmap Index Scan on tm_datebranchtype  (cost=0.00..1345.26 rows=1 width=0) (actual time=3.010..3.010 rows=0 loops=1)
                                  Index Cond: ((sale_date >= '2015-12-22'::date) AND (sale_date <= '2015-12-22'::date) AND ((transaction_type)::text = 'POSCN'::text))
                                ->  Bitmap Index Scan on tm_datebranchtype  (cost=0.00..1345.26 rows=1378 width=0) (actual time=3.087..3.087 rows=1889 loops=1)
                                      Index Cond: ((sale_date >= '2015-12-22'::date) AND (sale_date <= '2015-12-22'::date) AND ((transaction_type)::text = 'POSREF'::text))
                    ->  Hash  (cost=25.19..25.19 rows=519 width=18) (actual time=0.208..0.208 rows=519 loops=1)
                          Buckets: 1024  Batches: 1  Memory Usage: 26kB
                          ->  Seq Scan on branch_details b  (cost=0.00..25.19 rows=519 width=18) (actual time=0.006..0.119 rows=519 loops=1)
Planning time: 2.205 ms
Execution time: 14737.148 ms
排序(成本=1625242.60..1625417.63行=70012宽度=50)(实际时间=14732.852..14734.362行=72522循环=1)
排序键:m.sale\u日期
排序方法:快速排序内存:11496kB
->散列右连接(成本=90258.98..1619608.28行=70012宽度=50)(实际时间=11202.434..14710.938行=72522循环=1)
哈希条件:((l.link_guid)::text=(m.guid)::text)
->事务处理行项目l的顺序扫描(成本=0.00..1258955.88行=23879388宽度=62)(实际时间=0.050..6612.397行=25147461循环=1)
->散列(成本=89903.39..89903.39行=28447宽度=62)(实际时间=46.941..46.941行=42504循环=1)
存储桶:4096批:1内存使用率:3948kB
->散列联接(成本=4088.79..89903.39行=28447宽度=62)(实际时间=12.460..37.283行=42504循环=1)
散列条件:((m.branch\u代码)::text=(b.branch\u代码)::text)
->事务主机m上的位图堆扫描(成本=4057.12..89480.57行=28447宽度=52)(实际时间=12.240..21.802行=42504循环=1)
重新检查条件:((销售日期>='2015-12-22'::日期)和(销售日期='2015-12-22'::日期)和(销售日期='2015-12-22'::日期)和(销售日期位图(成本=4057.12..4057.12行=29508宽度=0)(实际时间=12.112..12.112行=0圈=1)
->tm_datebranchtype上的位图索引扫描(成本=0.00..1345.26行=28130宽度=0)(实际时间=6.013..6.013行=40615循环=1)
索引条件:((销售日期>='2015-12-22'::日期)和(销售日期位图索引扫描tm\U datebranchtype(成本=0.00..1345.26行=1宽度=0)(实际时间=3.010..3.010行=0循环=1)
索引条件:((销售日期>='2015-12-22'::日期)和(销售日期位图索引扫描tm\U datebranchtype(成本=0.00..1345.26行=1378宽度=0)(实际时间=3.087..3.087行=1889循环=1)
索引条件:((销售日期>='2015-12-22'::日期)和(销售日期散列(成本=25.19..25.19行=519宽度=18)(实际时间=0.208..0.208行=519循环=1)
存储桶:1024批:1内存使用率:26kB
->分支上的顺序扫描详细信息b(成本=0.00..25.19行=519宽度=18)(实际时间=0.006..0.119行=519圈=1)
计划时间:2.205毫秒
执行时间:14737.148毫秒
复制/读取服务器的结果需要111秒:

Sort  (cost=3792870.57..3793045.60 rows=70012 width=50) (actual time=111432.945..111436.554 rows=72522 loops=1)
  Sort Key: m.sale_date
  Sort Method: quicksort  Memory: 11496kB
  ->  Hash Join  (cost=95177.21..3787236.25 rows=70012 width=50) (actual time=62904.693..111410.002 rows=72522 loops=1)
        Hash Cond: ((m.branch_code)::text = (b.branch_code)::text)
        ->  Hash Right Join  (cost=95052.11..3778797.22 rows=70012 width=40) (actual time=62894.976..111265.547 rows=72522 loops=1)
              Hash Cond: ((l.link_guid)::text = (m.guid)::text)
              ->  Seq Scan on transaction_line_items l  (cost=0.00..3408100.80 rows=23879388 width=62) (actual time=0.010..96694.745 rows=25147447 loops=1)
              ->  Hash  (cost=92136.29..92136.29 rows=28447 width=52) (actual time=76.786..76.786 rows=42504 loops=1)
                    Buckets: 4096  Batches: 1  Memory Usage: 3527kB
                    ->  Bitmap Heap Scan on transaction_master m  (cost=4057.12..92136.29 rows=28447 width=52) (actual time=28.078..59.330 rows=42504 loops=1)
                          Recheck Cond: (((sale_date >= '2015-12-22'::date) AND (sale_date <= '2015-12-22'::date) AND ((transaction_type)::text = 'POSSALE'::text)) OR ((sale_date >= '2015-12-22'::date) AND (sale_date <= '2015-12-22'::date) AND ((transaction_type)::text = 'POSCN'::text)) OR ((sale_date >= '2015-12-22'::date) AND (sale_date <= '2015-12-22'::date) AND ((transaction_type)::text = 'POSREF'::text)))
                          Heap Blocks: exact=1095
                          ->  BitmapOr  (cost=4057.12..4057.12 rows=29508 width=0) (actual time=27.824..27.824 rows=0 loops=1)
                                ->  Bitmap Index Scan on tm_datebranchtype  (cost=0.00..1345.26 rows=28130 width=0) (actual time=14.828..14.828 rows=40615 loops=1)
                                      Index Cond: ((sale_date >= '2015-12-22'::date) AND (sale_date <= '2015-12-22'::date) AND ((transaction_type)::text = 'POSSALE'::text))
                                ->  Bitmap Index Scan on tm_datebranchtype  (cost=0.00..1345.26 rows=1 width=0) (actual time=6.552..6.552 rows=0 loops=1)
                                      Index Cond: ((sale_date >= '2015-12-22'::date) AND (sale_date <= '2015-12-22'::date) AND ((transaction_type)::text = 'POSCN'::text))
                                ->  Bitmap Index Scan on tm_datebranchtype  (cost=0.00..1345.26 rows=1378 width=0) (actual time=6.439..6.439 rows=1889 loops=1)
                                      Index Cond: ((sale_date >= '2015-12-22'::date) AND (sale_date <= '2015-12-22'::date) AND ((transaction_type)::text = 'POSREF'::text))
        ->  Hash  (cost=71.90..71.90 rows=519 width=18) (actual time=0.457..0.457 rows=519 loops=1)
              Buckets: 1024  Batches: 1  Memory Usage: 26kB
              ->  Seq Scan on branch_details b  (cost=0.00..71.90 rows=519 width=18) (actual time=0.009..0.259 rows=519 loops=1)
Planning time: 4.147 ms
Execution time: 111441.566 ms
排序(成本=3792870.57..3793045.60行=70012宽度=50)(实际时间=111432.945..111436.554行=72522圈=1)
排序键:m.sale\u日期
排序方法:快速排序内存:11496kB
->散列联接(成本=95177.21..3787236.25行=70012宽度=50)(实际时间=62904.693..111410.002行=72522循环=1)
散列条件:((m.branch\u代码)::text=(b.branch\u代码)::text)
->散列右连接(成本=95052.11..3778797.22行=70012宽度=40)(实际时间=62894.976..111265.547行=72522循环=1)
哈希条件:((l.link_guid)::text=(m.guid)::text)
->事务处理行项目l的顺序扫描(成本=0.00..3408100.80行=23879388宽度=62)(实际时间=0.010..96694.745行=25147447循环=1)
->散列(成本=92136.29..92136.29行=28447宽度=52)(实际时间=76.786..76.786行=42504循环=1)
存储桶:4096批:1内存使用量:3527kB
->事务主机m上的位图堆扫描(成本=4057.12..92136.29行=28447宽度=52)(实际时间=28.078..59.330行=42504循环=1)
重新检查条件:((销售日期>='2015-12-22'::日期)和(销售日期='2015-12-22'::日期)和(销售日期='2015-12-22'::日期)和(销售日期位图(成本=4057.12..4057.12行=29508宽度=0)(实际时间=27.824..27.824行=0圈=1)
->tm_datebranchtype上的位图索引扫描(成本=0.00..1345.26行=28130宽度=0)(实际时间=14.828..14.828行=40615循环=1)
索引条件:((销售日期>='2015-12-22'::日期)和(销售日期位图索引扫描tm\U datebranchtype(成本=0.00..1345.26行=1宽度=0)(实际时间=6.552..6.552行=0循环=1)
索引条件:((销售日期>='2015-12-22'::日期)和(销售日期位图索引扫描tm\U datebranchtype(成本=0.00..1345.26行=1378宽度=0)(实际时间=6.439..6.439行=1889循环=1)
索引条件:((销售日期>='2015-12-22'::日期)和(销售日期散列(成本=71.90..71.90行=519宽度=18)(实际时间=0.457..0.457行=519循环=1)
存储桶:1024批:1内存使用率:26kB
->分支上的顺序扫描详细信息b(成本=0.00..71.90行=519宽度=18)(实际时间=0.009..0.259行=519圈=1)
计划时间:4.147毫秒
执行时间:111441.566毫秒

在获得有关postgresql IRC频道的帮助后,我发现造成差异的原因是两台服务器上的cpu成本设置不同


一旦我更改了设置并重新加载了conf文件,两台服务器上的查询计划都是相同的。

您从何处更改了它?您将其更改为什么?默认设置为0.01,我将更新的设置为0.1,一旦我更改回默认设置,两台服务器上的查询计划都是相同的。但是,查询在读取时运行得慢得多由于服务器上的RAM较少(我假设RAM较少)