node-postgres simple SELECT变得非常慢(PostgreSQL)

时间:2017-03-10 16:16:59

标签: node.js postgresql postgresql-performance node-postgres

我正在开发一个支持postgresql的移动游戏的服务器端应用程序,我正在使用pg和Knex(“pg”:“6.1.2”和“knex”:“0.12.6”)。不久前,我遇到了选择性能退化的问题。最新的Postgresql和v4.7.2节点

我用40个虚构的ccu对我的应用进行了基准测试。所以我测量了Query构造函数和Query.prototype.handleReadyForQuery之间的时间以及我得到的内容:

{"select count(*) from \"player_battles\" where (\"attacking_player\" = $1 or \"defending_player\" = $2) and attacking_player <> defending_player": [27, 74, 92, 156, 170, 203, 217, 230, 243, 251, 261, 269, 288, 303, 313, 328, 342, 352, 361, 384, 395, 407, 420, 428, 440, 448, 460, 471, 483, 494, 507, 515, 537, 538, 539, 30, 40, 60, 1564, 2273, 2287, 2291, 2320, 2327, 2346, 2354, 2370, 2380, 2388, 2402, 2411, 2419, 2429, 2436, 2444, 4014, 4412, 4421, 4421, 4422, 4423, 4423, 4424, 4425, 4426, 4427, 4427, 4428, 4429, 4429, 18, 35, 60, 78, 113, 125, 151, 161, 170, 178, 185, 197, 611, 1972, 1987, 1988, 1988, 1989, 1991, 1992, 1993, 1993, 1994, 1995, 1996, 1996, 1997, 1997, 1999, 1999, 2000, 2001, 2002, 2002, 2002]}

(数字数组表示完成特定查询ms的次数)

卡尔,4429毫秒!令人不快的惊喜。

显然问题在于未经优化的sql或错误的索引,但使用pgBadger分析日志会向我显示:https://gyazo.com/4855a0eceac8669ab5c21564a392b357

有什么想法吗?

相关问题@ Github:https://github.com/brianc/node-postgres/issues/1243

上一个问题:Knex with PostgreSQL select query extremely performance degradation on multiple parallel requests

UPD 以下是“常规活动”的屏幕截图:https://gyazo.com/b2781069c87f88a2d4034345d58f91a3

UPD2

示例查询

SELECT COUNT(*)
FROM "player_battles"
WHERE ("attacking_player" = $1
   OR "defending_player" = $2)
   AND attacking_player <> defending_player

(其中$ 1和$ 2为12

目标表ddl

CREATE TABLE public.player_battles
(
    id integer NOT NULL DEFAULT nextval('player_battles_id_seq'::regclass),
    attacking_player integer NOT NULL,
    defending_player integer NOT NULL,
    is_attacking_won boolean NOT NULL,
    received_honor integer NOT NULL,
    lost_honor integer NOT NULL,
    gold_stolen bigint,
    created_at bigint NOT NULL DEFAULT '0'::bigint,
    attacking_level_atm integer NOT NULL DEFAULT 0,
    defending_level_atm integer NOT NULL DEFAULT 0,
    attacking_honor_atm integer NOT NULL DEFAULT 0,
    defending_honor_atm integer NOT NULL DEFAULT 0,
    no_winner boolean NOT NULL DEFAULT false,
    auto_defeat boolean,
    CONSTRAINT player_battles_pkey PRIMARY KEY (id),
    CONSTRAINT player_battles_attacking_player_foreign FOREIGN KEY     (attacking_player)
        REFERENCES public.player_profile (id) MATCH SIMPLE
        ON UPDATE NO ACTION
        ON DELETE NO ACTION,
    CONSTRAINT player_battles_defending_player_foreign FOREIGN KEY (defending_player)
        REFERENCES public.player_profile (id) MATCH SIMPLE
        ON UPDATE NO ACTION
        ON DELETE NO ACTION
)
WITH (
    OIDS = FALSE
)
TABLESPACE pg_default;

和索引

CREATE INDEX player_battles_attacking_player_index
ON public.player_battles USING btree
(attacking_player)
TABLESPACE pg_default;

CREATE INDEX player_battles_created_at_index
ON public.player_battles USING btree
(created_at DESC)
TABLESPACE pg_default;

CREATE INDEX player_battles_defending_player_index
ON public.player_battles USING btree
(defending_player)
TABLESPACE pg_default;

EXPLAIN ANALYZE

Aggregate  (cost=19.40..19.41 rows=1 width=8) (actual time=0.053..0.053 rows=1 loops=1)
  ->  Bitmap Heap Scan on player_battles  (cost=8.33..19.39 rows=4 width=0) (actual time=0.030..0.047 rows=4 loops=1)
        Recheck Cond: ((attacking_player = 1) OR (defending_player = 2))
        Filter: (attacking_player <> defending_player)
        Heap Blocks: exact=4
        ->  BitmapOr  (cost=8.33..8.33 rows=4 width=0) (actual time=0.021..0.021 rows=0 loops=1)
              ->  Bitmap Index Scan on player_battles_attacking_player_index  (cost=0.00..4.16 rows=2 width=0) (actual time=0.016..0.016 rows=2 loops=1)
                    Index Cond: (attacking_player = 1)
              ->  Bitmap Index Scan on player_battles_defending_player_index  (cost=0.00..4.16 rows=2 width=0) (actual time=0.003..0.003 rows=2 loops=1)
                    Index Cond: (defending_player = 2)
Planning time: 0.907 ms
Execution time: 0.160 ms

额外数据

player_battles中只有大约160名玩家和310行,但行数与问题无关。系统:DigitalOcean 2cpu / 2gb ram。 pgBadger的输出和node-postgres的响应时间:http://ge.tt/3DWk8Dj2

我的conf文件可能有所帮助:http://ge.tt/7cw69Dj2

0 个答案:

没有答案