Почему сумма (bigint) значительно быстрее, чем сумма (целое число) в PostgreSQL v10? - PullRequest
0 голосов
/ 12 ноября 2018
create table t_num_type(
   n_bigint bigint,
   n_numeric numeric,
   n_int int
);

insert into t_num_type
select generate_series(1,10000000),
       generate_series(1,10000000),
       generate_series(1,10000000);

1 »n_bigint

explain (analyze,buffers,format text)
select sum(n_bigint) from t_num_type;
Finalize Aggregate  (cost=116778.56..116778.57 rows=1 width=32) (actual time=1221.663..1221.664 rows=1 loops=1)
  Buffers: shared hit=23090
  ->  Gather  (cost=116778.34..116778.55 rows=2 width=32) (actual time=1221.592..1221.643 rows=3 loops=1)
        Workers Planned: 2
        Workers Launched: 2
        Buffers: shared hit=23090
        ->  Partial Aggregate  (cost=115778.34..115778.35 rows=1 width=32) (actual time=1217.558..1217.559 rows=1 loops=3)
              Buffers: shared hit=63695
              ->  Parallel Seq Scan on t_num_type  (cost=0.00..105361.67 rows=4166667 width=8) (actual time=0.021..747.748 rows=3333333 loops=3)
                    Buffers: shared hit=63695
Planning time: 0.265 ms
Execution time: 1237.360 ms

2» числовой

explain (analyze,buffers,format text)
select sum(n_numeric) from t_num_type;
Finalize Aggregate  (cost=116778.56..116778.57 rows=1 width=32) (actual time=1576.562..1576.562 rows=1 loops=1)
  Buffers: shared hit=22108
  ->  Gather  (cost=116778.34..116778.55 rows=2 width=32) (actual time=1576.502..1576.544 rows=3 loops=1)
        Workers Planned: 2
        Workers Launched: 2
        Buffers: shared hit=22108
        ->  Partial Aggregate  (cost=115778.34..115778.35 rows=1 width=32) (actual time=1572.446..1572.446 rows=1 loops=3)
              Buffers: shared hit=63695
              ->  Parallel Seq Scan on t_num_type  (cost=0.00..105361.67 rows=4166667 width=6) (actual time=0.028..781.808 rows=3333333 loops=3)
                    Buffers: shared hit=63695
Planning time: 0.157 ms
Execution time: 1592.559 ms

3 »n_int

explain (analyze,buffers,format text)
select sum(n_int) from t_num_type;
Finalize Aggregate  (cost=116778.55..116778.56 rows=1 width=8) (actual time=1247.065..1247.065 rows=1 loops=1)
  Buffers: shared hit=23367
  ->  Gather  (cost=116778.33..116778.54 rows=2 width=8) (actual time=1247.006..1247.055 rows=3 loops=1)
        Workers Planned: 2
        Workers Launched: 2
        Buffers: shared hit=23367
        ->  Partial Aggregate  (cost=115778.33..115778.34 rows=1 width=8) (actual time=1242.524..1242.524 rows=1 loops=3)
              Buffers: shared hit=63695
              ->  Parallel Seq Scan on t_num_type  (cost=0.00..105361.67 rows=4166667 width=4) (actual time=0.028..786.940 rows=3333333 loops=3)
                    Buffers: shared hit=63695
Planning time: 0.196 ms
Execution time: 1263.352 ms

pg9,6》

abase=# \timing
Timing is on.
abase=# select sum(n_bigint) from t_num_type;
      sum       
----------------
 50000005000000
(1 row)

Time: 2042.587 ms
abase=# select sum(n_numeric) from t_num_type;
      sum       
----------------
 50000005000000
(1 row)

Time: 1874.880 ms
abase=# select sum(n_int) from t_num_type;
      sum       
----------------
 50000005000000
(1 row)

Time: 1073.567 ms

pg10.4 101

 postgres=# select sum(n_bigint) from t_num_type;
          sum       
    ----------------
     50000005000000
    (1 row)

    Time: 871.811 ms
    postgres=# select sum(n_numeric) from t_num_type;
          sum       
    ----------------
     50000005000000
    (1 row)

    Time: 1168.779 ms (00:01.169)
    postgres=# select sum(n_int) from t_num_type;
          sum       
    ----------------
     50000005000000
    (1 row)

    Time: 923.551 ms

После многих тестов эффективность Sum pg10.4 была значительно улучшена, 9.6: сумма (int)> сумма (числовая)> сумма (bigint), pg10.4: sum (bigint)> sum (int):> sum (numeric)

Почему после нескольких тестов pg10: sum (bigint)> sum (int)?Значит ли это, что тип bigint рекомендуется больше?

1 Ответ

0 голосов
/ 12 ноября 2018

Во-первых, вы должны повторить эксперимент несколько раз, чтобы увидеть, остается ли разница такой же. Кэширование и другие эффекты вызывают определенные колебания времени запроса.

Я ожидаю, что разница между integer и bigint будет незначительной в долгосрочной перспективе. Обе операции суммирования должны быть реализованы аппаратно.

numeric должно быть значительно медленнее, потому что операции с этими двоично-десятичными десятичными числами реализованы в C в ядре базы данных.

Если bigint суммирование остается быстрее даже в повторяющихся экспериментах, мое единственное объяснение - деформация кортежа : чтобы добраться до третьего столбца, PostgreSQL должен обработать первые два столбца.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...