尽可能快地从数据库中获取搜索结果。问题是,即使在为搜索进行的每个字段创建索引之后,从PostgreSQL服务器返回的结果也非常缓慢:至少20秒。
有什么建议吗?
这是sql查询:
SELECT COUNT(*)
FROM "Part"
WHERE ("part_no"='aeroflex')
OR ("msn"='aeroflex')
OR ("nsn"='aeroflex')
OR ("name" ILIKE '%aeroflex%')
OR ("manufacturer" ILIKE '%aeroflex%')
OR ("mfg_sku"='aeroflex')
这是表的SQL转储,包含280万行
-- ----------------------------
-- Table structure for Part
-- ----------------------------
DROP TABLE IF EXISTS "electronic_parts"."Part";
CREATE TABLE "electronic_parts"."Part" (
"id" int4 NOT NULL DEFAULT nextval('"Part_id_seq"'::regclass),
"part_no" varchar COLLATE "default",
"manufacturer" varchar COLLATE "default",
"description" text COLLATE "default",
"slug" varchar COLLATE "default",
"nsn" varchar COLLATE "default",
"price" numeric,
"name" varchar COLLATE "default",
"mfg_sku" varchar COLLATE "default",
"msn" varchar COLLATE "default"
)
WITH (OIDS=FALSE);
ALTER TABLE "electronic_parts"."Part" OWNER TO "root";
-- ----------------------------
-- Primary key structure for table Part
-- ----------------------------
ALTER TABLE "electronic_parts"."Part" ADD PRIMARY KEY ("id") NOT DEFERRABLE INITIALLY IMMEDIATE;
-- ----------------------------
-- Indexes structure for table Part
-- ----------------------------
CREATE INDEX "part_i1" ON "electronic_parts"."Part" USING btree(msn COLLATE "default" "pg_catalog"."text_ops" ASC NULLS LAST);
CREATE INDEX "part_i2" ON "electronic_parts"."Part" USING gin(to_tsvector('english'::regconfig, name::text) "pg_catalog"."tsvector_ops") WITH (FASTUPDATE = YES);
CREATE INDEX "part_i2" ON "electronic_parts"."Part" USING gin(to_tsvector('english'::regconfig, name::text) "pg_catalog"."tsvector_ops") WITH (FASTUPDATE = YES);
CREATE INDEX "part_i3" ON "electronic_parts"."Part" USING gin(to_tsvector('english'::regconfig, manufacturer::text) "pg_catalog"."tsvector_ops") WITH (FASTUPDATE = YES);
CREATE INDEX "part_i3" ON "electronic_parts"."Part" USING gin(to_tsvector('english'::regconfig, manufacturer::text) "pg_catalog"."tsvector_ops") WITH (FASTUPDATE = YES);
CREATE INDEX "part_i4" ON "electronic_parts"."Part" USING gin(to_tsvector('english'::regconfig, description) "pg_catalog"."tsvector_ops") WITH (FASTUPDATE = YES);
CREATE INDEX "part_i4" ON "electronic_parts"."Part" USING gin(to_tsvector('english'::regconfig, description) "pg_catalog"."tsvector_ops") WITH (FASTUPDATE = YES);
CREATE UNIQUE INDEX "part_u1" ON "electronic_parts"."Part" USING btree(part_no COLLATE "default" "pg_catalog"."text_ops" ASC NULLS LAST);
CREATE UNIQUE INDEX "part_u2" ON "electronic_parts"."Part" USING btree(nsn COLLATE "default" "pg_catalog"."text_ops" ASC NULLS LAST);
CREATE UNIQUE INDEX "part_u3" ON "electronic_parts"."Part" USING btree(mfg_sku COLLATE "default" "pg_catalog"."text_ops" ASC NULLS LAST);
CREATE UNIQUE INDEX "part_u4" ON "electronic_parts"."Part" USING btree(slug COLLATE "default" "pg_catalog"."text_ops" ASC NULLS LAST);
以下是EXPLAIN
https://explain.depesz.com/s/5Lh
DB:x86_64-pc-linux-gnu上的PostgreSQL 9.5.6,由gcc编译(Ubuntu 5.4.0-6ubuntu1~16.04.4)5.4.0 20160609,64位
操作系统:Ubuntu 16.04.2 LTS
RAM:512MB(仅用于开发目的)
服务器上根本没有负载。目前测试为1个用户。
答案 0 :(得分:0)
可能,您的查询的以下两部分会降低速度:("name" ILIKE '%aeroflex%')
和("manufacturer" ILIKE '%aeroflex%')
。这样做的原因是,postgres不能使用常规索引与ilike运算符不能启动字符串(即它可以使用索引来加速{{1} },但不是'aeroflex%'
。
您的索引显示您对此进行了一些研究,通过使用'%aeroflex%'
创建索引,但to_tsvector
不使用这些索引,而是需要使用特殊运算符{{1与ilike
要利用已创建的to_tsvector索引,请使用where约束,如:
@@
或者,如果您更喜欢使用to_tsquery
和where to_tsvector('english', "name") @@ to_tsquery('english', 'aeroflex')
,则可以使用like
模块。
首先:激活模块
ilike
下一步:使用pgtrm
或CREATE EXTENSION pg_trgm;
like
您可以在文档页面https://www.postgresql.org/docs/current/static/pgtrgm.html中找到有关三元组的更多信息,也可以在https://www.postgresql.org/docs/current/static/datatype-textsearch.html的帖子中找到有关三元组的更多信息