To_Date() 扫描每个分区上的索引。我该如何优化它或者它是否可以(因为它不会慢很多)或切换到 pg11 来解决它?

To_Date() scans index on every partition. How can I optimize it or is it okay (as its not much slower) or switching to pg11 solve it?

我有一个分区 table tbl_ShiftAssignment。对数据类型为 TIMESTAMP WITHOUT TIMEZONE

的列 Shift_Date 进行分区

我正在使用 PostgreSQL 9.6.12

explain analyze
select * from tbl_shiftassignment 
where shift_date = to_date('15/01/19','dd/mm/yy')

即使是 TIMESTAMP WITHOUT TIMEZONE,我也需要从我的前端使用 TO_DATE(),否则没有输出。 如果我不使用 TO_DATE() 它只扫描单个分区。

现在看解释分析差异

''' sql 解释分析 select * 来自 tbl_shiftassignment shift_date = to_date('15/01/19','dd/mm/yy') ''''

> "Append  (cost=0.00..1000.01 rows=185 width=251) (actual
> time=0.611..1.106 rows=66 loops=1)" "  ->  Seq Scan on
> tbl_shiftassignment  (cost=0.00..0.00 rows=1 width=308) (actual
> time=0.015..0.015 rows=0 loops=1)" "        Filter: (shift_date =
> to_date('15/01/19'::text, 'dd/mm/yy'::text))" "  ->  Index Scan using
> isd_tbl_shiftassignment_2007 on tbl_shiftassignment_2007 
> (cost=0.15..8.17 rows=1 width=308) (actual time=0.055..0.055 rows=0
> loops=1)" "        Index Cond: (shift_date = to_date('15/01/19'::text,
> 'dd/mm/yy'::text))" "  ->  Index Scan using
> isd_tbl_shiftassignment_2008 on tbl_shiftassignment_2008 
> (cost=0.15..8.17 rows=1 width=308) (actual time=0.004..0.005 rows=0
> loops=1)" "        Index Cond: (shift_date = to_date('15/01/19'::text,
> 'dd/mm/yy'::text))" "  ->  Index Scan using
> isd_tbl_shiftassignment_2009 on tbl_shiftassignment_2009 
> (cost=0.15..8.17 rows=1 width=308) (actual time=0.003..0.003 rows=0
> loops=1)" "        Index Cond: (shift_date = to_date('15/01/19'::text,
> 'dd/mm/yy'::text))" "  ->  Index Scan using
> isd_tbl_shiftassignment_2010 on tbl_shiftassignment_2010 
> (cost=0.15..8.17 rows=1 width=308) (actual time=0.003..0.003 rows=0
> loops=1)" "        Index Cond: (shift_date = to_date('15/01/19'::text,
> 'dd/mm/yy'::text))" "  ->  Index Scan using
> isd_tbl_shiftassignment_2011 on tbl_shiftassignment_2011 
> (cost=0.15..8.17 rows=1 width=308) (actual time=0.006..0.006 rows=0
> loops=1)" "        Index Cond: (shift_date = to_date('15/01/19'::text,
> 'dd/mm/yy'::text))" "  ->  Index Scan using
> isd_tbl_shiftassignment_2012 on tbl_shiftassignment_2012 
> (cost=0.15..8.17 rows=1 width=308) (actual time=0.004..0.004 rows=0
> loops=1)" "        Index Cond: (shift_date = to_date('15/01/19'::text,
> 'dd/mm/yy'::text))" "  ->  Index Scan using
> isd_tbl_shiftassignment_2013 on tbl_shiftassignment_2013 
> (cost=0.15..8.17 rows=1 width=308) (actual time=0.005..0.005 rows=0
> loops=1)" "        Index Cond: (shift_date = to_date('15/01/19'::text,
> 'dd/mm/yy'::text))" "  ->  Index Scan using
> isd_tbl_shiftassignment_2014 on tbl_shiftassignment_2014 
> (cost=0.15..8.17 rows=1 width=308) (actual time=0.004..0.004 rows=0
> loops=1)" "        Index Cond: (shift_date = to_date('15/01/19'::text,
> 'dd/mm/yy'::text))" "  ->  Index Scan using
> isd_tbl_shiftassignment_2015 on tbl_shiftassignment_2015 
> (cost=0.15..8.17 rows=1 width=308) (actual time=0.003..0.003 rows=0
> loops=1)" "        Index Cond: (shift_date = to_date('15/01/19'::text,
> 'dd/mm/yy'::text))" "  ->  Index Scan using
> isd_tbl_shiftassignment_2016 on tbl_shiftassignment_2016 
> (cost=0.28..8.29 rows=1 width=183) (actual time=0.014..0.014 rows=0
> loops=1)" "        Index Cond: (shift_date = to_date('15/01/19'::text,
> 'dd/mm/yy'::text))" "  ->  Index Scan using
> isd_tbl_shiftassignment_201701 on tbl_shiftassignment_201701 
> (cost=0.28..8.19 rows=1 width=185) (actual time=0.010..0.010 rows=0
> loops=1)" "        Index Cond: (shift_date = to_date('15/01/19'::text,
> 'dd/mm/yy'::text))" "  ->  Index Scan using
> isd_tbl_shiftassignment_201702 on tbl_shiftassignment_201702 
> (cost=0.28..8.30 rows=1 width=190) (actual time=0.008..0.008 rows=0
> loops=1)" "        Index Cond: (shift_date = to_date('15/01/19'::text,
> 'dd/mm/yy'::text))" "  ->  Index Scan using
> isd_tbl_shiftassignment_201703 on tbl_shiftassignment_201703 
> (cost=0.28..8.30 rows=1 width=178) (actual time=0.008..0.008 rows=0
> loops=1)" "        Index Cond: (shift_date = to_date('15/01/19'::text,
> 'dd/mm/yy'::text))" "  ->  Index Scan using
> isd_tbl_shiftassignment_201704 on tbl_shiftassignment_201704 
> (cost=0.28..8.30 rows=1 width=184) (actual time=0.008..0.008 rows=0
> loops=1)" "        Index Cond: (shift_date = to_date('15/01/19'::text,
> 'dd/mm/yy'::text))" "  ->  Index Scan using
> isd_tbl_shiftassignment_201705 on tbl_shiftassignment_201705 
> (cost=0.28..8.30 rows=1 width=180) (actual time=0.051..0.051 rows=0
> loops=1)" "        Index Cond: (shift_date = to_date('15/01/19'::text,
> 'dd/mm/yy'::text))" "  ->  Index Scan using
> isd_tbl_shiftassignment_201706 on tbl_shiftassignment_201706 
> (cost=0.28..8.28 rows=1 width=185) (actual time=0.013..0.013 rows=0
> loops=1)" "        Index Cond: (shift_date = to_date('15/01/19'::text,
> 'dd/mm/yy'::text))" "  ->  Index Scan using
> isd_tbl_shiftassignment_201707 on tbl_shiftassignment_201707 
> (cost=0.28..8.30 rows=1 width=180) (actual time=0.010..0.010 rows=0
> loops=1)" "        Index Cond: (shift_date = to_date('15/01/19'::text,
> 'dd/mm/yy'::text))" "  ->  Index Scan using
> isd_tbl_shiftassignment_201708 on tbl_shiftassignment_201708 
> (cost=0.28..8.30 rows=1 width=185) (actual time=0.016..0.016 rows=0
> loops=1)" "        Index Cond: (shift_date = to_date('15/01/19'::text,
> 'dd/mm/yy'::text))" "  ->  Index Scan using
> isd_tbl_shiftassignment_201709 on tbl_shiftassignment_201709 
> (cost=0.28..8.30 rows=1 width=180) (actual time=0.033..0.033 rows=0
> loops=1)" "        Index Cond: (shift_date = to_date('15/01/19'::text,
> 'dd/mm/yy'::text))" "  ->  Index Scan using
> isd_tbl_shiftassignment_201710 on tbl_shiftassignment_201710 
> (cost=0.28..8.30 rows=1 width=185) (actual time=0.019..0.019 rows=0
> loops=1)" "        Index Cond: (shift_date = to_date('15/01/19'::text,
> 'dd/mm/yy'::text))" "  ->  Index Scan using
> isd_tbl_shiftassignment_201711 on tbl_shiftassignment_201711 
> (cost=0.28..6.06 rows=1 width=185) (actual time=0.010..0.010 rows=0
> loops=1)" "        Index Cond: (shift_date = to_date('15/01/19'::text,
> 'dd/mm/yy'::text))" "  ->  Index Scan using
> isd_tbl_shiftassignment_201712 on tbl_shiftassignment_201712 
> (cost=0.28..8.30 rows=1 width=180) (actual time=0.010..0.010 rows=0
> loops=1)" "        Index Cond: (shift_date = to_date('15/01/19'::text,
> 'dd/mm/yy'::text))" "  ->  Index Scan using
> isd_tbl_shiftassignment_201801 on tbl_shiftassignment_201801 
> (cost=0.28..8.30 rows=1 width=177) (actual time=0.011..0.011 rows=0
> loops=1)" "        Index Cond: (shift_date = to_date('15/01/19'::text,
> 'dd/mm/yy'::text))" "  ->  Index Scan using
> isd_tbl_shiftassignment_201802 on tbl_shiftassignment_201802 
> (cost=0.28..8.30 rows=1 width=185) (actual time=0.011..0.012 rows=0
> loops=1)" "        Index Cond: (shift_date = to_date('15/01/19'::text,
> 'dd/mm/yy'::text))" "  ->  Index Scan using
> isd_tbl_shiftassignment_201803 on tbl_shiftassignment_201803 
> (cost=0.28..8.25 rows=1 width=185) (actual time=0.018..0.018 rows=0
> loops=1)" "        Index Cond: (shift_date = to_date('15/01/19'::text,
> 'dd/mm/yy'::text))" "  ->  Index Scan using
> isd_tbl_shiftassignment_201804 on tbl_shiftassignment_201804 
> (cost=0.28..8.29 rows=1 width=185) (actual time=0.020..0.020 rows=0
> loops=1)" "        Index Cond: (shift_date = to_date('15/01/19'::text,
> 'dd/mm/yy'::text))" "  ->  Index Scan using
> isd_tbl_shiftassignment_201805 on tbl_shiftassignment_201805 
> (cost=0.28..8.30 rows=1 width=184) (actual time=0.012..0.012 rows=0
> loops=1)" "        Index Cond: (shift_date = to_date('15/01/19'::text,
> 'dd/mm/yy'::text))" "  ->  Index Scan using
> isd_tbl_shiftassignment_201806 on tbl_shiftassignment_201806 
> (cost=0.28..8.26 rows=1 width=180) (actual time=0.012..0.012 rows=0
> loops=1)" "        Index Cond: (shift_date = to_date('15/01/19'::text,
> 'dd/mm/yy'::text))" "  ->  Index Scan using
> isd_tbl_shiftassignment_201807 on tbl_shiftassignment_201807 
> (cost=0.28..8.30 rows=1 width=178) (actual time=0.019..0.019 rows=0
> loops=1)" "        Index Cond: (shift_date = to_date('15/01/19'::text,
> 'dd/mm/yy'::text))" "  ->  Index Scan using
> isd_tbl_shiftassignment_201808 on tbl_shiftassignment_201808 
> (cost=0.28..8.30 rows=1 width=179) (actual time=0.014..0.014 rows=0
> loops=1)" "        Index Cond: (shift_date = to_date('15/01/19'::text,
> 'dd/mm/yy'::text))" "  ->  Index Scan using
> isd_tbl_shiftassignment_201809 on tbl_shiftassignment_201809 
> (cost=0.28..8.26 rows=1 width=185) (actual time=0.078..0.078 rows=0
> loops=1)" "        Index Cond: (shift_date = to_date('15/01/19'::text,
> 'dd/mm/yy'::text))" "  ->  Index Scan using
> isd_tbl_shiftassignment_201810 on tbl_shiftassignment_201810 
> (cost=0.28..8.21 rows=1 width=185) (actual time=0.018..0.018 rows=0
> loops=1)" "        Index Cond: (shift_date = to_date('15/01/19'::text,
> 'dd/mm/yy'::text))" "  ->  Index Scan using
> isd_tbl_shiftassignment_201811 on tbl_shiftassignment_201811 
> (cost=0.28..8.22 rows=1 width=184) (actual time=0.017..0.017 rows=0
> loops=1)" "        Index Cond: (shift_date = to_date('15/01/19'::text,
> 'dd/mm/yy'::text))" "  ->  Index Scan using
> isd_tbl_shiftassignment_201812 on tbl_shiftassignment_201812 
> (cost=0.28..8.30 rows=1 width=184) (actual time=0.017..0.017 rows=0
> loops=1)" "        Index Cond: (shift_date = to_date('15/01/19'::text,
> 'dd/mm/yy'::text))" "  ->  Bitmap Heap Scan on
> tbl_shiftassignment_201901  (cost=4.79..35.78 rows=66 width=186)
> (actual time=0.040..0.086 rows=66 loops=1)" "        Recheck Cond:
> (shift_date = to_date('15/01/19'::text, 'dd/mm/yy'::text))" "       
> Heap Blocks: exact=12" "        ->  Bitmap Index Scan on
> isd_tbl_shiftassignment_201901  (cost=0.00..4.78 rows=66 width=0)
> (actual time=0.030..0.030 rows=66 loops=1)" "              Index Cond:
> (shift_date = to_date('15/01/19'::text, 'dd/mm/yy'::text))" "  -> 
> Index Scan using isd_tbl_shiftassignment_201902 on
> tbl_shiftassignment_201902  (cost=0.28..8.30 rows=1 width=185) (actual
> time=0.014..0.014 rows=0 loops=1)" "        Index Cond: (shift_date =
> to_date('15/01/19'::text, 'dd/mm/yy'::text))" "  ->  Index Scan using
> isd_tbl_shiftassignment_201903 on tbl_shiftassignment_201903 
> (cost=0.15..8.17 rows=1 width=308) (actual time=0.006..0.006 rows=0
> loops=1)" "        Index Cond: (shift_date = to_date('15/01/19'::text,
> 'dd/mm/yy'::text))" "  ->  Index Scan using
> isd_tbl_shiftassignment_201904 on tbl_shiftassignment_201904 
> (cost=0.15..8.17 rows=1 width=308) (actual time=0.005..0.005 rows=0
> loops=1)" "        Index Cond: (shift_date = to_date('15/01/19'::text,
> 'dd/mm/yy'::text))" "  ->  Index Scan using
> isd_tbl_shiftassignment_201905 on tbl_shiftassignment_201905 
> (cost=0.15..8.17 rows=1 width=308) (actual time=0.005..0.005 rows=0
> loops=1)" "        Index Cond: (shift_date = to_date('15/01/19'::text,
> 'dd/mm/yy'::text))" "  ->  Index Scan using
> isd_tbl_shiftassignment_201906 on tbl_shiftassignment_201906 
> (cost=0.15..8.17 rows=1 width=308) (actual time=0.005..0.005 rows=0
> loops=1)" "        Index Cond: (shift_date = to_date('15/01/19'::text,
> 'dd/mm/yy'::text))" "  ->  Index Scan using
> isd_tbl_shiftassignment_201907 on tbl_shiftassignment_201907 
> (cost=0.15..8.17 rows=1 width=308) (actual time=0.003..0.003 rows=0
> loops=1)" "        Index Cond: (shift_date = to_date('15/01/19'::text,
> 'dd/mm/yy'::text))" "  ->  Index Scan using
> isd_tbl_shiftassignment_201908 on tbl_shiftassignment_201908 
> (cost=0.15..8.17 rows=1 width=308) (actual time=0.004..0.004 rows=0
> loops=1)" "        Index Cond: (shift_date = to_date('15/01/19'::text,
> 'dd/mm/yy'::text))" "  ->  Index Scan using
> isd_tbl_shiftassignment_201909 on tbl_shiftassignment_201909 
> (cost=0.15..8.17 rows=1 width=308) (actual time=0.005..0.005 rows=0
> loops=1)" "        Index Cond: (shift_date = to_date('15/01/19'::text,
> 'dd/mm/yy'::text))" "  ->  Index Scan using
> isd_tbl_shiftassignment_201910 on tbl_shiftassignment_201910 
> (cost=0.15..8.17 rows=1 width=308) (actual time=0.004..0.004 rows=0
> loops=1)" "        Index Cond: (shift_date = to_date('15/01/19'::text,
> 'dd/mm/yy'::text))" "  ->  Index Scan using
> isd_tbl_shiftassignment_201911 on tbl_shiftassignment_201911 
> (cost=0.15..8.17 rows=1 width=308) (actual time=0.005..0.005 rows=0
> loops=1)" "        Index Cond: (shift_date = to_date('15/01/19'::text,
> 'dd/mm/yy'::text))" "  ->  Index Scan using
> isd_tbl_shiftassignment_201912 on tbl_shiftassignment_201912 
> (cost=0.15..8.17 rows=1 width=308) (actual time=0.005..0.005 rows=0
> loops=1)" "        Index Cond: (shift_date = to_date('15/01/19'::text,
> 'dd/mm/yy'::text))" "  ->  Index Scan using
> isd_tbl_shiftassignment_202001 on tbl_shiftassignment_202001 
> (cost=0.15..8.17 rows=1 width=308) (actual time=0.005..0.005 rows=0
> loops=1)" "        Index Cond: (shift_date = to_date('15/01/19'::text,
> 'dd/mm/yy'::text))" "  ->  Index Scan using
> isd_tbl_shiftassignment_202002 on tbl_shiftassignment_202002 
> (cost=0.15..8.17 rows=1 width=308) (actual time=0.005..0.005 rows=0
> loops=1)" "        Index Cond: (shift_date = to_date('15/01/19'::text,
> 'dd/mm/yy'::text))" "  ->  Index Scan using
> isd_tbl_shiftassignment_202003 on tbl_shiftassignment_202003 
> (cost=0.15..8.17 rows=1 width=308) (actual time=0.004..0.004 rows=0
> loops=1)" "        Index Cond: (shift_date = to_date('15/01/19'::text,
> 'dd/mm/yy'::text))" "  ->  Index Scan using
> isd_tbl_shiftassignment_202004 on tbl_shiftassignment_202004 
> (cost=0.15..8.17 rows=1 width=308) (actual time=0.005..0.005 rows=0
> loops=1)" "        Index Cond: (shift_date = to_date('15/01/19'::text,
> 'dd/mm/yy'::text))" "  ->  Index Scan using
> isd_tbl_shiftassignment_202005 on tbl_shiftassignment_202005 
> (cost=0.15..8.17 rows=1 width=308) (actual time=0.006..0.007 rows=0
> loops=1)" "        Index Cond: (shift_date = to_date('15/01/19'::text,
> 'dd/mm/yy'::text))" "  ->  Index Scan using
> isd_tbl_shiftassignment_202006 on tbl_shiftassignment_202006 
> (cost=0.15..8.17 rows=1 width=308) (actual time=0.003..0.003 rows=0
> loops=1)" "        Index Cond: (shift_date = to_date('15/01/19'::text,
> 'dd/mm/yy'::text))" "  ->  Index Scan using
> isd_tbl_shiftassignment_202007 on tbl_shiftassignment_202007 
> (cost=0.15..8.17 rows=1 width=308) (actual time=0.004..0.004 rows=0
> loops=1)" "        Index Cond: (shift_date = to_date('15/01/19'::text,
> 'dd/mm/yy'::text))" "  ->  Index Scan using
> isd_tbl_shiftassignment_202008 on tbl_shiftassignment_202008 
> (cost=0.15..8.17 rows=1 width=308) (actual time=0.005..0.005 rows=0
> loops=1)" "        Index Cond: (shift_date = to_date('15/01/19'::text,
> 'dd/mm/yy'::text))" "  ->  Index Scan using
> isd_tbl_shiftassignment_202009 on tbl_shiftassignment_202009 
> (cost=0.15..8.17 rows=1 width=308) (actual time=0.003..0.004 rows=0
> loops=1)" "        Index Cond: (shift_date = to_date('15/01/19'::text,
> 'dd/mm/yy'::text))" "  ->  Index Scan using
> isd_tbl_shiftassignment_202010 on tbl_shiftassignment_202010 
> (cost=0.15..8.17 rows=1 width=308) (actual time=0.003..0.003 rows=0
> loops=1)" "        Index Cond: (shift_date = to_date('15/01/19'::text,
> 'dd/mm/yy'::text))" "  ->  Index Scan using
> isd_tbl_shiftassignment_202011 on tbl_shiftassignment_202011 
> (cost=0.15..8.17 rows=1 width=308) (actual time=0.004..0.004 rows=0
> loops=1)" "        Index Cond: (shift_date = to_date('15/01/19'::text,
> 'dd/mm/yy'::text))" "  ->  Index Scan using
> isd_tbl_shiftassignment_202012 on tbl_shiftassignment_202012 
> (cost=0.15..8.17 rows=1 width=308) (actual time=0.003..0.003 rows=0
> loops=1)"
> 
> "  ->  Index Scan using isd_tbl_shiftassignment_posdata on
> tbl_shiftassignment_posdata  (cost=0.15..8.17 rows=1 width=308)
> (actual time=0.004..0.004 rows=0 loops=1)" "        Index Cond:
> (shift_date = to_date('15/01/19'::text, 'dd/mm/yy'::text))" "Planning
> time: 68.388 ms" "Execution time: 4.535 ms"

=============================================

然而,如果我不像这个那样使用 TO_DATE()...

explain analyze
select * from tbl_shiftassignment 
where shift_date = '15-JAN-19';


"Append  (cost=0.00..35.61 rows=67 width=187) (actual time=0.023..0.041 rows=66 loops=1)"
"  ->  Seq Scan on tbl_shiftassignment  (cost=0.00..0.00 rows=1 width=308) (actual time=0.006..0.006 rows=0 loops=1)"
"        Filter: (shift_date = '2019-01-15 00:00:00'::timestamp without time zone)"
"  ->  Bitmap Heap Scan on tbl_shiftassignment_201901  (cost=4.79..35.61 rows=66 width=186) (actual time=0.016..0.032 rows=66 loops=1)"
"        Recheck Cond: (shift_date = '2019-01-15 00:00:00'::timestamp without time zone)"
"        Heap Blocks: exact=12"
"        ->  Bitmap Index Scan on isd_tbl_shiftassignment_201901  (cost=0.00..4.77 rows=66 width=0) (actual time=0.011..0.011 rows=66 loops=1)"
"              Index Cond: (shift_date = '2019-01-15 00:00:00'::timestamp without time zone)"
"Planning time: 7.388 ms"
"Execution time: 0.088 ms"

如果不使用,只有 10 行受到影响 TO_DATE()

虽然索引扫描速度很快,但我的问题是如果我切换到 pg11,即使我使用 TO_DATE()

它是否会像第二个示例中那样运行(仅影响 10 行)
Same problem for Date Range 
WHERE Shift_Date >= TO_DATE('25/08/2018','DD/MM/YYYY')
AND Shift_Date <= TO_DATE('30/08/2018','DD/MM/YYYY')

是的,这是 PostgreSQL v11 中的新功能:分区修剪也可以在执行时发生。

在 PostgreSQL v10 中,分区修剪只能在计划查询时发生。由于 to_dateSTABLE 而不是 IMMUTABLE,因此在计划时执行 可能会 导致与执行时不同的值,因此计划器无法优化它。

如果您使用 date 文字编写查询,它应该适用于 v10。