los*_*rse 3 sql postgresql postgresql-9.3
我有一张大的(3000万行)简单的桌子...
CREATE TABLE "Foo"."Bar" (
"BarID" BIGSERIAL PRIMARY KEY,
"DateTime" TIMESTAMP NOT NULL,
"Bar" TEXT NOT NULL
);
Run Code Online (Sandbox Code Playgroud)
...一个简单的索引:
CREATE INDEX ON "Foo"."Bar"("DateTime");
Run Code Online (Sandbox Code Playgroud)
...和一个简单的问题:
在2015年的第一个小时,哪些"BarID"值具有"DateTime"价值?
因此,我进行了以下查询#1:
SELECT
"Bar"."BarID"
FROM
"Foo"."Bar"
WHERE
"Bar"."DateTime" <@ TSRANGE('2015-01-01 00:00:00', '2015-01-01 01:00:00');
Run Code Online (Sandbox Code Playgroud)
...以及此查询#2:
SELECT
"Bar"."BarID"
FROM
"Foo"."Bar"
WHERE
"Bar"."DateTime" BETWEEN '2015-01-01 00:00:00' AND '2015-01-01 01:00:00';
Run Code Online (Sandbox Code Playgroud)
查询#1在60秒内通过序列扫描运行。
使用索引扫描,查询2在0.02秒内运行。
我尝试制作另一个USING GiST没有改善的索引。
是什么赋予了?
范围表达式是可修饰的。您只需要一个范围表达式可以使用的索引。在“时间戳”类型的列上有一个B树索引和一个GiST索引。时间戳范围表达式不能利用这些索引中的任何一个。
在时间戳范围表达式上创建GiST索引,并更新统计信息。
create index on "Foo"."Bar"
using gist(tsrange("DateTime"::timestamp, "DateTime"::timestamp, '[]'));
analyze "Foo"."Bar";
Run Code Online (Sandbox Code Playgroud)
你的“日期时间”列表示在时间点,所以时间戳范围表达应具有包容性降低和上限('[]')。
重写WHERE子句以使用相同的表达式。
explain analyze
select "BarID"
from "Foo"."Bar"
where tsrange("DateTime"::timestamp, "DateTime"::timestamp, '[]') <@ tsrange('2015-01-01 00:00:00', '2015-01-01 01:00:00');
Run Code Online (Sandbox Code Playgroud)
该查询可以使用索引,它在大约一百万行的表上大约半毫秒内在此处运行。
“在“条形图”上进行位图堆扫描(成本= 10.19..859.53行= 246宽度= 8)(实际时间= 0.195..0.551行= 219循环= 1)” “重新检查条件:(tsrange(“ DateTime”,“ DateTime”,'[]':: text)<@'[“ 2015-01-01 00:00:00”,“ 2015-01-01 01:00: 00“)':: tsrange)” “->在“ Bar_tsrange_idx”上进行位图索引扫描(成本= 0.00..10.13行= 246宽度= 0)(实际时间= 0.160..0.160行= 219循环= 1)” “索引条件:(tsrange(“ DateTime”,“ DateTime”,'[]':: text)<@'[“ 2015-01-01 00:00:00”,“ 2015-01-01 01:00: 00“)':: tsrange)” “总运行时间:0.589毫秒”
| 归档时间: |
|
| 查看次数: |
319 次 |
| 最近记录: |