Postgresql 时间戳上的分区表::日期查询扫描所有分区 问题设置(Postgesql 9.6)
我有一个表,其中分区按我的预期工作(1),一个不按我的预期工作(2): 案例(1) 表,不带时区的s_日期时间戳分区不为空Postgresql 时间戳上的分区表::日期查询扫描所有分区 问题设置(Postgesql 9.6),postgresql,time,timezone,partitioning,postgresql-9.6,Postgresql,Time,Timezone,Partitioning,Postgresql 9.6,我有一个表,其中分区按我的预期工作(1),一个不按我的预期工作(2): 案例(1) 表,不带时区的s_日期时间戳分区不为空 CREATE TABLE "diagnoseAW"."AWIORECORDERAWCOMMAND" ( "ebpZone" text COLLATE pg_catalog."default" NOT NULL, "elementName" text COLLATE pg_catalog."default" NOT NULL, command text
CREATE TABLE "diagnoseAW"."AWIORECORDERAWCOMMAND"
(
"ebpZone" text COLLATE pg_catalog."default" NOT NULL,
"elementName" text COLLATE pg_catalog."default" NOT NULL,
command text COLLATE pg_catalog."default" NOT NULL,
s_date timestamp without time zone NOT NULL,
i_io_value text COLLATE pg_catalog."default" NOT NULL,
source text COLLATE pg_catalog."default",
time_created timestamp with time zone,
user_created text COLLATE pg_catalog."default",
CONSTRAINT "AWIORECORDERAWCOMMAND_pkey" PRIMARY KEY ("ebpZone", "elementName", command, s_date, i_io_value)
USING INDEX TABLESPACE s1297_index
)
WITH (
OIDS = FALSE
)
TABLESPACE s1297_data;
CREATE TABLE "diagnoseAW"."AWIORECORDERMOVEMENT"
(
event text COLLATE pg_catalog."default",
"ebpZone" text COLLATE pg_catalog."default" NOT NULL,
"awName" text COLLATE pg_catalog."default" NOT NULL,
"startDate" timestamp with time zone NOT NULL,
"lossDate" timestamp with time zone NOT NULL,
"controlDate" timestamp with time zone NOT NULL,
"startDuration" numeric,
"totalDuration" numeric,
time_created timestamp with time zone,
user_created text COLLATE pg_catalog."default",
"lossEnd" boolean,
"controlEnd" boolean,
railtemp double precision,
airtemp double precision,
CONSTRAINT "AWIORECORDERMOVEMENT_pkey" PRIMARY KEY ("ebpZone", "awName", "startDate", "lossDate", "controlDate")
USING INDEX TABLESPACE s1297_index
)
WITH (
OIDS = FALSE
)
TABLESPACE s1297_data;
分区如下所示:
CREATE TABLE partitions."AWIORECORDERAWCOMMAND_2018_02_20"
(
"ebpZone" ,
"elementName" ,
command ,
s_date ,
i_io_value ,
source ,
time_created ,
user_created ,
CONSTRAINT "AWIORECORDERAWCOMMAND_2018_02_20_NEW_pkey" PRIMARY KEY ("ebpZone", "elementName", command, s_date, i_io_value)
USING INDEX TABLESPACE s1297_data,
CONSTRAINT "AWIORECORDERAWCOMMAND_2018_02_20_s_date_check" CHECK (s_date::date = '2018-02-20'::date)
)
INHERITS ("diagnoseAW"."AWIORECORDERAWCOMMAND")
WITH (
OIDS = FALSE
)
TABLESPACE s1297_data;
CREATE TABLE partitions."AWIORECORDERMOVEMENT_2018_02_20"
(
event ,
"ebpZone" ,
"awName" ,
"startDate" ,
"lossDate" ,
"controlDate" ,
"startDuration" ,
"totalDuration" ,
time_created ,
user_created ,
"lossEnd" ,
"controlEnd" ,
railtemp ,
airtemp ,
CONSTRAINT "AWIORECORDERMOVEMENT_2018_02_20_NEW_pkey" PRIMARY KEY ("ebpZone", "awName", "startDate", "lossDate", "controlDate")
USING INDEX TABLESPACE s1297_data,
CONSTRAINT "AWIORECORDERMOVEMENT_2018_02_20_startDate_check" CHECK ("startDate"::date = '2018-02-20'::date)
)
INHERITS ("diagnoseAW"."AWIORECORDERMOVEMENT")
WITH (
OIDS = FALSE
)
TABLESPACE s1297_data;
执行此查询时:
SELECT "ebpZone", "elementName", command, s_date, i_io_value, source, time_created, user_created
FROM "diagnoseAW"."AWIORECORDERAWCOMMAND"
WHERE s_date::date = '2018-02-20'::date;
SELECT event, "ebpZone", "awName", "startDate", "lossDate", "controlDate", "startDuration", "totalDuration", time_created, user_created, "lossEnd", "controlEnd", railtemp, airtemp
FROM "diagnoseAW"."AWIORECORDERMOVEMENT"
WHERE "startDate"::date='2018-02-20'::date;
它工作正常,只扫描想要的分区:
"Append (cost=0.00..3083.05 rows=610 width=48)"
" -> Seq Scan on "AWIORECORDERAWCOMMAND" (cost=0.00..0.00 rows=1 width=208)"
" Filter: ((s_date)::date = '2018-02-20'::date)"
" -> Seq Scan on "AWIORECORDERAWCOMMAND_2018_02_20" (cost=0.00..3083.05 rows=609 width=48)"
" Filter: ((s_date)::date = '2018-02-20'::date)"
案例(2):
表,在时区不为NULL的“startDate”时间戳上分区
CREATE TABLE "diagnoseAW"."AWIORECORDERAWCOMMAND"
(
"ebpZone" text COLLATE pg_catalog."default" NOT NULL,
"elementName" text COLLATE pg_catalog."default" NOT NULL,
command text COLLATE pg_catalog."default" NOT NULL,
s_date timestamp without time zone NOT NULL,
i_io_value text COLLATE pg_catalog."default" NOT NULL,
source text COLLATE pg_catalog."default",
time_created timestamp with time zone,
user_created text COLLATE pg_catalog."default",
CONSTRAINT "AWIORECORDERAWCOMMAND_pkey" PRIMARY KEY ("ebpZone", "elementName", command, s_date, i_io_value)
USING INDEX TABLESPACE s1297_index
)
WITH (
OIDS = FALSE
)
TABLESPACE s1297_data;
CREATE TABLE "diagnoseAW"."AWIORECORDERMOVEMENT"
(
event text COLLATE pg_catalog."default",
"ebpZone" text COLLATE pg_catalog."default" NOT NULL,
"awName" text COLLATE pg_catalog."default" NOT NULL,
"startDate" timestamp with time zone NOT NULL,
"lossDate" timestamp with time zone NOT NULL,
"controlDate" timestamp with time zone NOT NULL,
"startDuration" numeric,
"totalDuration" numeric,
time_created timestamp with time zone,
user_created text COLLATE pg_catalog."default",
"lossEnd" boolean,
"controlEnd" boolean,
railtemp double precision,
airtemp double precision,
CONSTRAINT "AWIORECORDERMOVEMENT_pkey" PRIMARY KEY ("ebpZone", "awName", "startDate", "lossDate", "controlDate")
USING INDEX TABLESPACE s1297_index
)
WITH (
OIDS = FALSE
)
TABLESPACE s1297_data;
分区如下所示:
CREATE TABLE partitions."AWIORECORDERAWCOMMAND_2018_02_20"
(
"ebpZone" ,
"elementName" ,
command ,
s_date ,
i_io_value ,
source ,
time_created ,
user_created ,
CONSTRAINT "AWIORECORDERAWCOMMAND_2018_02_20_NEW_pkey" PRIMARY KEY ("ebpZone", "elementName", command, s_date, i_io_value)
USING INDEX TABLESPACE s1297_data,
CONSTRAINT "AWIORECORDERAWCOMMAND_2018_02_20_s_date_check" CHECK (s_date::date = '2018-02-20'::date)
)
INHERITS ("diagnoseAW"."AWIORECORDERAWCOMMAND")
WITH (
OIDS = FALSE
)
TABLESPACE s1297_data;
CREATE TABLE partitions."AWIORECORDERMOVEMENT_2018_02_20"
(
event ,
"ebpZone" ,
"awName" ,
"startDate" ,
"lossDate" ,
"controlDate" ,
"startDuration" ,
"totalDuration" ,
time_created ,
user_created ,
"lossEnd" ,
"controlEnd" ,
railtemp ,
airtemp ,
CONSTRAINT "AWIORECORDERMOVEMENT_2018_02_20_NEW_pkey" PRIMARY KEY ("ebpZone", "awName", "startDate", "lossDate", "controlDate")
USING INDEX TABLESPACE s1297_data,
CONSTRAINT "AWIORECORDERMOVEMENT_2018_02_20_startDate_check" CHECK ("startDate"::date = '2018-02-20'::date)
)
INHERITS ("diagnoseAW"."AWIORECORDERMOVEMENT")
WITH (
OIDS = FALSE
)
TABLESPACE s1297_data;
执行此查询时:
SELECT "ebpZone", "elementName", command, s_date, i_io_value, source, time_created, user_created
FROM "diagnoseAW"."AWIORECORDERAWCOMMAND"
WHERE s_date::date = '2018-02-20'::date;
SELECT event, "ebpZone", "awName", "startDate", "lossDate", "controlDate", "startDuration", "totalDuration", time_created, user_created, "lossEnd", "controlEnd", railtemp, airtemp
FROM "diagnoseAW"."AWIORECORDERMOVEMENT"
WHERE "startDate"::date='2018-02-20'::date;
它无法正常工作,它会扫描所有分区:
"Append (cost=0.00..1386483.44 rows=241434 width=80)"
" -> Seq Scan on "AWIORECORDERMOVEMENT" (cost=0.00..0.00 rows=1 width=242)"
" Filter: (("startDate")::date = '2018-02-20'::date)"
" -> Seq Scan on "AWIORECORDERMOVEMENT_2017_01_02" (cost=0.00..2566.48 rows=446 width=80)"
" Filter: (("startDate")::date = '2018-02-20'::date)"
" -> Seq Scan on "AWIORECORDERMOVEMENT_2017_01_07" (cost=0.00..1588.55 rows=276 width=80)"
" Filter: (("startDate")::date = '2018-02-20'::date)"
" -> Seq Scan on "AWIORECORDERMOVEMENT_2017_01_09" (cost=0.00..3137.61 rows=546 width=80)"
" Filter: (("startDate")::date = '2018-02-20'::date)"
" -> Seq Scan on "AWIORECORDERMOVEMENT_2017_01_12" (cost=0.00..3279.47 rows=569 width=80)"
" Filter: (("startDate")::date = '2018-02-20'::date)"
" -> Seq Scan on "AWIORECORDERMOVEMENT_2017_01_13" (cost=0.00..3390.38 rows=589 width=80)"
" Filter: (("startDate")::date = '2018-02-20'::date)"
" -> Seq Scan on "AWIORECORDERMOVEMENT_2017_01_16" (cost=0.00..3139.07 rows=546 width=80)"
" Filter: (("startDate")::date = '2018-02-20'::date)"
问题:
我看到的唯一区别是我用于分区的时间戳中有无时间戳。(同样在第二种情况下,分区有索引,在第一种情况下没有,但我认为这不相关)
你知道我如何做一个不会扫描所有分区的查询吗?最好我不会重新加载所有的数十亿行。我们没有找到正确的方法,我们最终改变了表,在不到三个小时的时间内将列从带时区的时间戳转换为不带时区的时间戳。这当然是一个有趣的问题。如果我有时间的话,我可能会调查一下。