我使用Postgresql,这是我的表:
CREATE TABLE tbl_cdr
(
uid serial NOT NULL,
start_time timestamp without time zone NOT NULL,
end_time timestamp without time zone NOT NULL,
error_code smallint NOT NULL DEFAULT 200,
src_ip character varying(20),
src_port smallint,
dest_ip character varying(20),
dest_port smallint,
CONSTRAINT tbl_cdr_pkey PRIMARY KEY (uid)
)
WITH (
OIDS=FALSE
);
CREATE INDEX idx_tbl_cdr_date
ON tbl_cdr
USING btree
((start_time::date));
CREATE INDEX idx_tbl_cdr_end_time
ON tbl_cdr
USING btree
(end_time);
CREATE INDEX idx_tbl_cdr_start_time
ON tbl_cdr
USING btree
(start_time);
我有一个查询(postgresql),如:
(
select *
from tbl_cdr
where cast(start_time as date) in
(
select cast(start_time as date) as times
from tbl_cdr
where ( cast(start_time as date) >= '2016-04-30 22:00:00' and cast(start_time as date) <= '2016-09-30 20:00:00' )
and ( extract(hour from start_time) >= 22 and extract(hour from start_time) <= 24)
group by times order by times limit 5
)
and ( cast(start_time as date) >= '2016-04-30 22:00:00' and cast(start_time as date) <= '2016-09-30 20:00:00' )
and ( extract(hour from start_time) >= 22 and extract(hour from start_time) <= 24)
)
UNION
(
select *
from tbl_cdr
where cast(start_time as date) in
(
select cast(start_time as date) as times
from tbl_cdr
where ( cast(start_time as date) >= '2016-05-01 22:00:00' and cast(start_time as date) <= '2016-09-30 20:00:00' )
and ( extract(hour from start_time) >= 0 and extract(hour from start_time) < 20)
group by times order by times limit 5
)
and ( cast(start_time as date) >= '2016-05-01 22:00:00' and cast(start_time as date) <= '2016-09-30 20:00:00' )
and ( extract(hour from start_time) >= 0 and extract(hour from start_time) < 20)
)
order by start_time asc
但是效果很慢。
您对性能改进有什么建议吗?
我尝试了以下索引:
CREATE INDEX idx_tbl_cdr_date_casted ON tbl_cdr ( cast(start_time as date) );
CREATE INDEX idx_tbl_cdr_hour_casted ON tbl_cdr ( extract(hour from start_time) );
但这些没有帮助:)
这是分析输出:
"Sort (cost=311262.22..311333.53 rows=28524 width=179)"
" Sort Key: tbl_cdr.start_time"
" -> Unique (cost=305045.14..306613.96 rows=28524 width=179)"
" -> Sort (cost=305045.14..305116.45 rows=28524 width=179)"
" Sort Key: tbl_cdr.uid, tbl_cdr.start_time, tbl_cdr.end_time, (...)"
" -> Append (cost=75581.47..300396.88 rows=28524 width=179)"
" -> Hash Semi Join (cost=75581.47..150055.82 rows=14262 width=179)"
" Hash Cond: ((tbl_cdr.start_time)::date = ((tbl_cdr_1.start_time)::date))"
" -> Bitmap Heap Scan on tbl_cdr (cost=608.80..74830.00 rows=28523 width=179)"
" Recheck Cond: ((date_part('hour'::text, start_time) >= 22::double precision) AND (date_part('hour'::text, start_time) <= 24::double precision))"
" Filter: (((start_time)::date >= '2016-04-30'::date) AND ((start_time)::date <= '2016-09-30'::date))"
" -> Bitmap Index Scan on idx_tbl_cdr_hour_casted (cost=0.00..601.67 rows=28523 width=0)"
" Index Cond: ((date_part('hour'::text, start_time) >= 22::double precision) AND (date_part('hour'::text, start_time) <= 24::double precision))"
" -> Hash (cost=74972.66..74972.66 rows=1 width=4)"
" -> Limit (cost=74972.64..74972.65 rows=1 width=8)"
" -> Sort (cost=74972.64..74972.65 rows=1 width=8)"
" Sort Key: ((tbl_cdr_1.start_time)::date)"
" -> HashAggregate (cost=74972.62..74972.63 rows=1 width=8)"
" Group Key: (tbl_cdr_1.start_time)::date"
" -> Bitmap Heap Scan on tbl_cdr tbl_cdr_1 (cost=608.80..74901.31 rows=28523 width=8)"
" Recheck Cond: ((date_part('hour'::text, start_time) >= 22::double precision) AND (date_part('hour'::text, start_time) <= 24::double precision))"
" Filter: (((start_time)::date >= '2016-04-30'::date) AND ((start_time)::date <= '2016-09-30'::date))"
" -> Bitmap Index Scan on idx_tbl_cdr_hour_casted (cost=0.00..601.67 rows=28523 width=0)"
" Index Cond: ((date_part('hour'::text, start_time) >= 22::double precision) AND (date_part('hour'::text, start_time) <= 24::double precision))"
" -> Hash Semi Join (cost=75581.47..150055.82 rows=14262 width=179)"
" Hash Cond: ((tbl_cdr_2.start_time)::date = ((tbl_cdr_3.start_time)::date))"
" -> Bitmap Heap Scan on tbl_cdr tbl_cdr_2 (cost=608.80..74830.00 rows=28523 width=179)"
" Recheck Cond: ((date_part('hour'::text, start_time) >= 0::double precision) AND (date_part('hour'::text, start_time) < 20::double precision))"
" Filter: (((start_time)::date >= '2016-05-01'::date) AND ((start_time)::date <= '2016-09-30'::date))"
" -> Bitmap Index Scan on idx_tbl_cdr_hour_casted (cost=0.00..601.67 rows=28523 width=0)"
" Index Cond: ((date_part('hour'::text, start_time) >= 0::double precision) AND (date_part('hour'::text, start_time) < 20::double precision))"
" -> Hash (cost=74972.66..74972.66 rows=1 width=4)"
" -> Limit (cost=74972.64..74972.65 rows=1 width=8)"
" -> Sort (cost=74972.64..74972.65 rows=1 width=8)"
" Sort Key: ((tbl_cdr_3.start_time)::date)"
" -> HashAggregate (cost=74972.62..74972.63 rows=1 width=8)"
" Group Key: (tbl_cdr_3.start_time)::date"
" -> Bitmap Heap Scan on tbl_cdr tbl_cdr_3 (cost=608.80..74901.31 rows=28523 width=8)"
" Recheck Cond: ((date_part('hour'::text, start_time) >= 0::double precision) AND (date_part('hour'::text, start_time) < 20::double precision))"
" Filter: (((start_time)::date >= '2016-05-01'::date) AND ((start_time)::date <= '2016-09-30'::date))"
" -> Bitmap Index Scan on idx_tbl_cdr_hour_casted (cost=0.00..601.67 rows=28523 width=0)"
" Index Cond: ((date_part('hour'::text, start_time) >= 0::double precision) AND (date_part('hour'::text, start_time) < 20::double precision))"