问题及环境
1.有两张数据库表exception_invoice_status_log和invoice_exception_status,其中exception_invoice_status_log数据量10w左右,invoice_exception_status数据量可以忽略
2.两张表数据库结构如下
sql
CREATE TABLE IF NOT EXISTS "exception_invoice_status_log"
(
"invoice_status_log_id" BIGINT,
"exception_status_id" BIGINT,
CONSTRAINT "pk_eisl_invoice_status_id_exception_status_id" PRIMARY KEY ("invoice_status_log_id", "exception_status_id"),
CONSTRAINT "fk_eisl_exception_status_id" FOREIGN KEY ("exception_status_id") REFERENCES "invoice_exception_status" ("id")
);
CREATE TABLE IF NOT EXISTS "invoice_exception_status"
(
"id" INT NOT NULL,
"name" VARCHAR(20) NOT NULL,
CONSTRAINT "pk_invoice_exception_status" PRIMARY KEY ("id")
);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
3.现有数据库查询如下,查询效率非常psql低下
sql
SELECT "ies"."name"
FROM "exception_invoice_status_log" "eisl"
LEFT JOIN "invoice_exception_status" "ies"
ON ("eisl"."invoice_status_log_id" = 1000 AND "eisl"."exception_status_id" = "ies"."id")
ORDER BY "eisl"."exception_status_id"
1
2
3
4
5
2
3
4
5
原因分析
1.先分析查询语句
发现LEFT JOIN的条件并没有走索引 而是过滤条件
2.将LEFT JOIN修改为JOIN分析
sql
SELECT "ies"."name"
FROM "exception_invoice_status_log" "eisl",
"invoice_exception_status" "ies"
WHERE "eisl"."invoice_status_log_id" = 1000
AND "eisl"."exception_status_id" = "ies"."id"
ORDER BY "eisl"."exception_status_id"
1
2
3
4
5
6
2
3
4
5
6
发现使用JOIN后查询条件走的是主键索引
结论
在postgresql中,若非联合主键,使用LEFT JOIN且条件为主键关联时,会使用主键索引。
若是联合主键,LEFT JOIN用主键关联不会走主键索引,使用JOIN会。