我在 Ubuntu 12.04 上使用 PostgreSQL 9.1。
我需要在一个时间范围内选择记录:我的表time_limits有两个timestamp字段和一个integer属性。我的实际表中还有其他列与此查询无关。
create table (
start_date_time timestamp,
end_date_time timestamp,
id_phi integer,
primary key(start_date_time, end_date_time,id_phi);
Run Code Online (Sandbox Code Playgroud)
该表包含大约 200 万条记录。
像下面这样的查询花费了大量的时间:
select * from time_limits as t
where t.id_phi=0
and t.start_date_time <= timestamp'2010-08-08 00:00:00'
and t.end_date_time >= timestamp'2010-08-08 00:05:00';
Run Code Online (Sandbox Code Playgroud)
所以我尝试添加另一个索引 - PK的倒数:
create index idx_inversed on time_limits(id_phi, start_date_time, end_date_time);
Run Code Online (Sandbox Code Playgroud)
我的印象是性能有所提高:访问表中间记录的时间似乎更合理:介于 40 到 90 秒之间。
但是对于时间范围中间的值,它仍然是几十秒。在针对表格末尾时(按时间顺序),还有两次。
我explain analyze第一次尝试得到这个查询计划:
Bitmap Heap Scan on time_limits (cost=4730.38..22465.32 rows=62682 width=36) (actual time=44.446..44.446 rows=0 loops=1)
Recheck …Run Code Online (Sandbox Code Playgroud) 我在表中有一个像 fr(fromid,toid) 这样的唯一复合键,当我使用解释运行查询时,我得到以下结果:
Impossible WHERE noticed after reading const tables`
Run Code Online (Sandbox Code Playgroud)
我运行的查询:
explain SELECT rid FROM relationship WHERE fromid=78 AND toid=60
Run Code Online (Sandbox Code Playgroud)
有什么帮助吗?
EDIT1:
当我使用以下查询时:
explain SELECT rid FROM relationship WHERE fromid=60 and toid=78 AND is_approved='s' OR is_approved='f' OR is_approved='t'
Run Code Online (Sandbox Code Playgroud)
我看到的USING WHERE不是之前的消息,但是当我使用以下查询时:
explain SELECT rid FROM relationship WHERE fromid=60 and toid=78 AND (is_approved='s' OR is_approved='f' OR is_approved='t')
Run Code Online (Sandbox Code Playgroud)
我再次收到第一条impossible ...消息!这些括号在这里做什么?
编辑2:
CREATE TABLE `relationship` (
`rid` int(10) unsigned NOT NULL AUTO_INCREMENT,
`fromid` mediumint(8) unsigned NOT NULL,
`toid` mediumint(8) unsigned …Run Code Online (Sandbox Code Playgroud) 我在 PostgreSQL 9.3 中使用了一个 PL/pgSQL 函数,里面有几个复杂的查询:
create function f1()
returns integer as
$$
declare
event tablename%ROWTYPE;
....
....
begin
FOR event IN
SELECT * FROM tablename WHERE condition
LOOP
EXECUTE 'SELECT f2(event.columnname)' INTO dummy_return;
END LOOP;
...
INSERT INTO ... FROM a LEFT JOIN b ... LEFT JOIN c WHERE ...
UPDATE T SET cl1 = M.cl1 FROM M WHERE M.pkcols = T.pkcols;
...
end
$$ language plpgsql;
Run Code Online (Sandbox Code Playgroud)
如果我跑了EXPLAIN ANALYZE f1(),我只会得到总时间,但没有细节。有没有办法可以获得函数中所有查询的详细结果?
如果函数中的查询不应该被 Postgres 优化,我也会要求解释。
这个查询:select count(*) from planner_event需要很长时间才能运行 - 太长了,我在它完成之前放弃并杀死了它。但是,当我运行时explain select count(*) from planner_event,我可以在输出中看到一列带有行数 (14m)。
为什么explain可以立即得到行数,而count(*)却需要很长时间才能运行?
当我对给定查询运行 EXPLAIN ANALYZE 命令时,我很难解释输出的时间值。例如(实际时间=8163.890..8163.893)。内部小数是否代表重复字符?抱歉,这可能是一个菜鸟问题,但我想确保我正确解释了结果。
-> GroupAggregate (cost=2928781.21..2929243.02 rows=1 width=27712) (actual time=8163.890..8163.893 rows=1 loops=1)
Run Code Online (Sandbox Code Playgroud) 我运行一个EXPLAIN:
mysql> explain select last_name from employees order by last_name;
+----+-------------+-----------+------+---------------+------+---------+------+-------+----------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-----------+------+---------------+------+---------+------+-------+----------------+
| 1 | SIMPLE | employees | ALL | NULL | NULL | NULL | NULL | 10031 | Using filesort |
+----+-------------+-----------+------+---------------+------+---------+------+-------+----------------+
1 row in set (0.00 sec)
Run Code Online (Sandbox Code Playgroud)
我表中的索引:
mysql> show index from employees;
+-----------+------------+---------------+--------------+---------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | …Run Code Online (Sandbox Code Playgroud) 我有这个查询:
EXPLAIN (ANALYZE, BUFFERS)
SELECT * FROM test
WHERE
timestamp_range @> '2015-01-22 23:00:00'::timestamp
AND data_int_array @> '{49, 61}'::integer[];
Run Code Online (Sandbox Code Playgroud)
哪些输出:
Bitmap Heap Scan on test (cost=16.74..20.75 rows=1 width=113) (actual time=0.364..0.367 rows=2 loops=1)
Recheck Cond: ((timestamp_range @> '2015-01-22 23:00:00'::timestamp without time zone) AND (data_int_array @> '{49,61}'::integer[]))
Heap Blocks: exact=1
Buffers: shared hit=8
-> BitmapAnd (cost=16.74..16.74 rows=1 width=0) (actual time=0.351..0.351 rows=0 loops=1)
Buffers: shared hit=7
-> Bitmap Index Scan on ix_test_interval (cost=0.00..4.40 rows=17 width=0) (actual time=0.130..0.130 rows=12 loops=1)
Index Cond: (timestamp_range @> '2015-01-22 …Run Code Online (Sandbox Code Playgroud) 此查询仅扫描一份文档并仅返回一份文档。但这非常慢:
2017-05-22T07:13:24.548+0000 I COMMAND [conn40] query databasename.collectionname query: { _id: ObjectId('576d4ce3f2d62a001e84a9b8') } planSummary: IDHACK ntoskip:0 keysExamined:1 docsExamined:1 idhack:1 cursorExhausted:1 keyUpdates:0 writeConflicts:0 numYields:0 nreturned:1 reslen:42 locks:{ Global: { acquireCount: { r: 2 } }, Database: { acquireCount: { r: 1 } }, Collection: { acquireCount: { r: 1 } } } 8009ms
2017-05-22T07:13:24.549+0000 I COMMAND [conn10] query databasename.collectionname query: { _id: ObjectId('576d4db35de5fa001ebdd77a') } planSummary: IDHACK ntoskip:0 keysExamined:1 docsExamined:1 idhack:1 cursorExhausted:1 keyUpdates:0 writeConflicts:0 numYields:0 nreturned:1 reslen:42 locks:{ Global: { acquireCount: { r: …Run Code Online (Sandbox Code Playgroud) 我EXPLAIN (ANALYZE, BUFFERS) SELECT ...在我的 Postgres 9.3 服务器上运行。我最终Buffers: shared hit=166416 dirtied=2在输出中看到了类似的东西。
从文档中,“脏”表示:
脏的块数表示此查询更改的先前未修改的块数;而写入的块数表示该后端在查询处理期间从缓存中逐出的先前脏块的数量。
这听起来像是将块标记为脏的过程应该只在更新数据时发生。SELECT但是,我的查询是,并且只读取数据。我想它只会报告点击或阅读。我显然错了。但是,在这种情况下到底发生了什么?
对于糟糕的列/表名称感到抱歉,但由于这是一个工作项目,我想确保可以询问。我只是希望至少了解为什么我没有看到我的功能索引被使用,所以我觉得在生产环境中添加这些索引更好。
该查询使用我创建的视图,该视图具有许多不同的列,其中包含执行以下操作的 where 子句:
....
AND e.sysid = NVL(wi.ALPHAid, -999)
AND NVL(wi.ALPHAid, -999) <> -999
AND NVL(wi.BRAVOid, -999) = -999
AND NVL(wi.CHARLIEid, -999) = -999
...
Run Code Online (Sandbox Code Playgroud)
我的理解是,如果您通过函数传递列,则 Oracle 不能使用索引,而您需要创建基于函数的索引。因此,在创建索引之前,我在解释计划中获得了以下成本:
计划哈希值:1233409744
-------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 223 | 56 (6)| 00:00:01 |
| 1 | SORT ORDER BY | | 1 | 223 | 56 (6)| 00:00:01 |
| 2 …Run Code Online (Sandbox Code Playgroud) explain ×10
postgresql ×5
index ×3
mysql ×3
optimization ×3
cache ×1
count ×1
functions ×1
innodb ×1
mongodb ×1
mongodb-3.2 ×1
oracle ×1
performance ×1
plpgsql ×1
slow-log ×1