我有 18M 行的视频表。当我按 ID 搜索特定视频时,最多需要 6 秒才能完成。有时需要几毫秒,有时长达 6 秒,但平均约为 2 秒。
应用程序托管在 heroku 上,我正在使用带有 410MB RAM 的Crane 数据库 ( https://addons.heroku.com/heroku-postgresql )。
有什么办法可以加快这个速度吗?我平均每秒查询 50 次视频,新视频以每秒 50 次的速度插入/更新。
explain analyze SELECT * FROM videos WHERE id = 17841464 LIMIT 1;
QUERY PLAN
----------------------------------------------------------------------------------------------------------------------------------
Limit (cost=0.00..6.43 rows=1 width=119) (actual time=2337.892..2337.894 rows=1 loops=1)
-> Index Scan using videos_pkey on videos (cost=0.00..6.43 rows=1 width=119) (actual time=2337.888..2337.888 rows=1 loops=1)
Index Cond: (id = 17841464)
Total runtime: 2337.943 ms
表格如下所示:
\d+ videos;
Table "public.videos"
Column | Type | Modifiers | Storage | Stats target | Description
----------------+-----------------------------+-----------------------------------------------------+----------+--------------+-------------
id | integer | not null default nextval('videos_id_seq'::regclass) | plain | |
uuid | character(11) | not null | extended | |
channel_id | integer | not null | plain | |
category_id | integer | | plain | |
title | character varying(255) | | extended | |
published_at | timestamp without time zone | | plain | |
view_count | bigint | | plain | |
like_count | integer | | plain | |
dislike_count | integer | | plain | |
favorite_count | integer | | plain | |
comment_count | integer | | plain | |
disabled | boolean | default false | plain | |
created_at | timestamp without time zone | | plain | |
updated_at | timestamp without time zone | | plain | |
Indexes:
"videos_pkey" PRIMARY KEY, btree (id)
"videos_uuid_idx" UNIQUE, btree (uuid)
"videos_latest_by_channel_idx" btree (channel_id, published_at DESC)
"videos_top_by_channel_idx" btree (channel_id, view_count DESC)
Has OIDs: no
老实说,我从未见过单个值 btree 查找需要这么长时间。我不认为您的问题只是在您的查询中。我认为它在其他地方。
首先你说你有很多写。这可能意味着您不断地从缓冲区中推出大量内容并执行大量随机磁盘 I/O。如果很多瓶颈在于一般 I/O 和您的 RAM 不足,我不会感到惊讶。
对于 1800 万行,这些看起来不是很大。它们可能都适合记忆。
无论如何,如果可以访问服务器上的命令行,首先要做的就是占用 CPU I/O 等待时间与用户时间与系统时间(您可以在代码的其他地方执行此操作)。还运行解释 (ANALYSE, BUFFERS, VERBOSE) 集,以便您可以看到更多关于正在发生的事情。如果您的问题是 CPU 活动不足、RAM 缓慢或大量磁盘 I/O,这些应该可以让您了解,但事实上,可以做的事情很少。
您可以做的另一件事是:
看看这是否加快了速度。