postgresql SELECT DISTINCT运行速度非常慢
此查询立即运行:postgresql SELECT DISTINCT运行速度非常慢,postgresql,Postgresql,此查询立即运行: mydb=# SELECT reports.* FROM reports WHERE reports.id = 9988 ORDER BY time DESC LIMIT 1; 运行此查询花费了33秒(我在这里只选择了单位id为9988的报告。我可能有数百个,如果没有数千个的话): (更新:这是使用EXPLAIN ANALYZIE的结果): 报表表的架构如下所示: mydb=# \d+ reports
mydb=# SELECT reports.* FROM reports WHERE reports.id = 9988 ORDER BY time DESC LIMIT 1;
运行此查询花费了33秒(我在这里只选择了单位id为9988的报告。我可能有数百个,如果没有数千个的话):
(更新:这是使用EXPLAIN ANALYZIE的结果):
报表表的架构如下所示:
mydb=# \d+ reports
Table "public.reports"
Column | Type | Modifiers | Storage | Description
----------------+-----------------------------+------------------------------------------------------+----------+-------------
id | integer | not null default nextval('reports_id_seq'::regclass) | plain |
unit_id | integer | not null | plain |
time_secs | integer | not null | plain |
time | timestamp without time zone | | plain |
latitude | numeric(15,10) | not null | main |
longitude | numeric(15,10) | not null | main |
speed | integer | | plain |
io | integer | | plain |
msg_type | integer | | plain |
msg_code | integer | | plain |
signal | integer | | plain |
cellid | integer | | plain |
lac | integer | | plain |
processed | boolean | default false | plain |
created_at | timestamp without time zone | | plain |
updated_at | timestamp without time zone | | plain |
street | character varying(255) | | extended |
county | character varying(255) | | extended |
state | character varying(255) | | extended |
postal_code | character varying(255) | | extended |
country | character varying(255) | | extended |
distance | numeric | | main |
gps_valid | boolean | default true | plain |
city | character varying(255) | | extended |
street_number | character varying(255) | | extended |
address_source | integer | | plain |
source | integer | default 0 | plain |
driver_id | integer | | plain |
Indexes:
"reports_pkey" PRIMARY KEY, btree (id)
"reports_uniqueness_index" UNIQUE, btree (unit_id, "time", latitude, longitude)
"index_reports_on_address_source" btree (address_source DESC)
"index_reports_on_driver_id" btree (driver_id)
"index_reports_on_time" btree ("time")
"index_reports_on_time_secs" btree (time_secs)
"index_reports_on_unit_id" btree (unit_id)
Foreign-key constraints:
"reports_driver_id_fkey" FOREIGN KEY (driver_id) REFERENCES drivers(id)
"reports_unit_id_fkey" FOREIGN KEY (unit_id) REFERENCES units(id)
Referenced by:
TABLE "alerts" CONSTRAINT "alerts_report_id_fkey" FOREIGN KEY (report_id) REFERENCES reports(id)
TABLE "pressure_transmitters" CONSTRAINT "pressure_transmitters_report_id_fkey" FOREIGN KEY (report_id) REFERENCES reports(id)
TABLE "thermoking" CONSTRAINT "thermoking_report_id_fkey" FOREIGN KEY (report_id) REFERENCES reports(id)
Has OIDs: no
为什么SELECT DISTINCT的运行速度如此之慢?重新检查时位图堆扫描速度相对较慢-请尝试增加工时_mem第一种情况下,将在唯一键上查找报告,甚至不必按或限制执行订单,因为始终会有一次点击,因此应该非常快。在上的
distinct之前,您在第二次查询中的命中率是多少?您的查询的差异不仅仅是“distinct”。您的where子句和order by也不同。因此,第一个查询作为比较并不有用。对于感兴趣的查询,请参见此处,了解您应该提供给我们的更多信息:我更新了问题以使用解释分析。您能详细说明一下吗?将工时增加到什么?你应该找到一个最佳值(也许我错了)。试一试:将work_mem设置为“800MB”;解释分析。。。请参阅有关此问题的博客800mb???我只是运行ShowAll来显示运行时参数的设置。而work_mem当前设置为1mb。你认为我应该把它增加到800mb吗?这将是一个巨大的增长,不是吗?您可以在会话中更改它,只是为了这个测试查询。1MB美国默认值,太低了-找到一些关于PostgreSQL初始配置的文章-通常OLTP的设置为4..10MB,OLAP的设置为400..800MB。
mydb=# \d+ reports
Table "public.reports"
Column | Type | Modifiers | Storage | Description
----------------+-----------------------------+------------------------------------------------------+----------+-------------
id | integer | not null default nextval('reports_id_seq'::regclass) | plain |
unit_id | integer | not null | plain |
time_secs | integer | not null | plain |
time | timestamp without time zone | | plain |
latitude | numeric(15,10) | not null | main |
longitude | numeric(15,10) | not null | main |
speed | integer | | plain |
io | integer | | plain |
msg_type | integer | | plain |
msg_code | integer | | plain |
signal | integer | | plain |
cellid | integer | | plain |
lac | integer | | plain |
processed | boolean | default false | plain |
created_at | timestamp without time zone | | plain |
updated_at | timestamp without time zone | | plain |
street | character varying(255) | | extended |
county | character varying(255) | | extended |
state | character varying(255) | | extended |
postal_code | character varying(255) | | extended |
country | character varying(255) | | extended |
distance | numeric | | main |
gps_valid | boolean | default true | plain |
city | character varying(255) | | extended |
street_number | character varying(255) | | extended |
address_source | integer | | plain |
source | integer | default 0 | plain |
driver_id | integer | | plain |
Indexes:
"reports_pkey" PRIMARY KEY, btree (id)
"reports_uniqueness_index" UNIQUE, btree (unit_id, "time", latitude, longitude)
"index_reports_on_address_source" btree (address_source DESC)
"index_reports_on_driver_id" btree (driver_id)
"index_reports_on_time" btree ("time")
"index_reports_on_time_secs" btree (time_secs)
"index_reports_on_unit_id" btree (unit_id)
Foreign-key constraints:
"reports_driver_id_fkey" FOREIGN KEY (driver_id) REFERENCES drivers(id)
"reports_unit_id_fkey" FOREIGN KEY (unit_id) REFERENCES units(id)
Referenced by:
TABLE "alerts" CONSTRAINT "alerts_report_id_fkey" FOREIGN KEY (report_id) REFERENCES reports(id)
TABLE "pressure_transmitters" CONSTRAINT "pressure_transmitters_report_id_fkey" FOREIGN KEY (report_id) REFERENCES reports(id)
TABLE "thermoking" CONSTRAINT "thermoking_report_id_fkey" FOREIGN KEY (report_id) REFERENCES reports(id)
Has OIDs: no