Postgresql Postgres以错误的顺序返回记录
我有相当大的表信息。它包含大约100mil记录 运行简单查询时:Postgresql Postgres以错误的顺序返回记录,postgresql,indexing,sql-order-by,corruption,Postgresql,Indexing,Sql Order By,Corruption,我有相当大的表信息。它包含大约100mil记录 运行简单查询时: select uid from messages order by uid asc limit 1000 结果很奇怪。开始时的记录是可以的,但是它们并不总是按列uid排序 这里是分析 Limit (cost=0.00..3740.51 rows=1000 width=4) (actual time=0.009..4.630 rows=1000 loops=1) Output: uid -> Index S
select uid from messages order by uid asc limit 1000
结果很奇怪。开始时的记录是可以的,但是它们并不总是按列uid排序
这里是分析
Limit (cost=0.00..3740.51 rows=1000 width=4) (actual time=0.009..4.630 rows=1000 loops=1)
Output: uid
-> Index Scan using messages_pkey on public.messages (cost=0.00..376250123.91 rows=100587944 width=4) (actual time=0.009..4.150 rows=1000 loops=1)
Output: uid
Total runtime: 4.796 ms
PostgreSQL 9.1.12
该表始终处于高负载(插入、更新、删除)下,并且几乎一直处于自动清空状态。这会导致问题吗
UPD。添加了表定义。抱歉,无法添加完整的表定义,但所有重要字段及其类型都在此处
# \d+ messages
Table "public.messages"
Column | Type | Modifiers | Storage | Description
--------------+-----------------------------+--------------------------------------------------------+----------+-------------
uid | integer | not null default nextval('messages_uid_seq'::regclass) | plain |
code | character(22) | not null | extended |
created | timestamp without time zone | not null | plain |
accountid | integer | not null | plain |
status | character varying(20) | not null | extended |
hash | character(3) | not null | extended |
xxxxxxxx | timestamp without time zone | not null | plain |
xxxxxxxx | integer | | plain |
xxxxxxxx | character varying(255) | | extended |
xxxxxxxx | text | not null | extended |
xxxxxxxx | character varying(250) | not null | extended |
xxxxxxxx | text | | extended |
xxxxxxxx | text | not null | extended |
Indexes:
"messages_pkey" PRIMARY KEY, btree (uid)
"messages_unique_code" UNIQUE CONSTRAINT, btree (code)
"messages_accountid_created_idx" btree (accountid, created)
"messages_accountid_hash_idx" btree (accountid, hash)
"messages_accountid_status_idx" btree (accountid, status)
Has OIDs: no
下面是一个非常笼统的答案: 尝试: 在同一会话中重新运行查询 如果结果的顺序与启用索引扫描时的顺序不同,则索引已损坏 在这种情况下,请使用以下方法进行修复:
REINDEX INDEX index_name;
避免在没有索引的情况下运行查询的漫长等待。问题很可能是由于索引已损坏。马上修理,看看是否能解决问题
因为您的表
创建索引
命令
以及在下列情况下:
使用此选项时,PostgreSQL将在不使用
获取任何阻止并发插入、更新或删除的锁
在桌子上;而标准索引构建会锁定写操作(但不会
阅读)放在桌子上直到完成。有几点需要注意
知道何时使用此选项-请参阅
因此,我建议:
ALTER TABLE news DROP CONSTRAINT messages_pkey;
CREATE UNIQUE INDEX CONCURRENTLY messages_pkey ON news (uid);
ALTER TABLE news ADD PRIMARY KEY USING INDEX messages_pkey;
最后一步只是对系统目录的一个小小的更新。您是按字面意思记录的吗
[space]965…
?如果是这样的话,它们很可能是按字符串排序的,空格比数字“低”。如果您按uid:int进行排序,是否有区别?您的表定义在这里是必须的。我们需要查看uid
的数据类型。在psql中发布您通过\d消息获得的信息。谢谢。添加了表定义您使用什么程序来运行此查询?好的,我使用indexscan=off启动了查询,但此表中有100mil记录,因此需要很长时间才能完成查询。似乎您是对的。在indexscan=关闭的情况下,结果是正确的。谢谢你创建索引是我不相信的一种魔法。特别是在实时服务器上。我认为最好在复制服务器上清空整个表,然后将应用程序的路由切换到数据库。真空吸尘器会帮上大忙吗?@neon你为什么不相信同时创建索引呢?你有任何证据证明它不起作用吗?
REINDEX INDEX index_name;
CONCURRENTLY
ALTER TABLE news DROP CONSTRAINT messages_pkey;
CREATE UNIQUE INDEX CONCURRENTLY messages_pkey ON news (uid);
ALTER TABLE news ADD PRIMARY KEY USING INDEX messages_pkey;