我正在开发一个支持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为1
和2
)
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;
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