复合索引(也称为联合索引)的使用遵循“最左前缀原则”。这意味着查询条件必须从索引定义的最左边开始,并且连续地匹配索引中的列,才能有效地使用该索引。具体到你提到的复合索引 abc,它意味着索引按照 a、b 和 c 列的顺序进行排序。
根据这一原则,以下情况可以有效利用复合索引 abc:
1,查询条件包含 a,则可以使用索引。
2,查询条件包含 a 和 b,则可以使用索引。
3,查询条件包含 a、b 和 c,则可以使用索引。
但是,以下情况不能有效利用复合索引 abc:
1,如果查询只包含 c,则不能使用索引,因为没有从最左前缀开始。
2,如果查询包含 c 和 a,但由于没有包含 b,也不能使用索引。
对于你提到的查询 c a 和 ac:
c a:这个查询顺序不正确,因为没有从索引的最左前缀 a 开始,所以复合索引 abc 不能被使用。
ac:这个查询也不能使用复合索引 abc,因为尽管它从 a 开始,但在 c 出现之前缺少了 b,打破了连续性。
因此,复合索引 abc 只能在查询条件从 a 开始并连续包含 b 和 c 的情况下被有效使用。如果需要优化涉及 c 和 a 的查询,可能需要创建一个额外的复合索引,如 ca 或者 cba,具体取决于查询模式和表的使用情况。在设计复合索引时,应考虑到最常见的查询模式,以确保索引能够被有效地利用。
二,验证
PostgreSQL 数据库中创建一个学生信息表tbl_student_info ,包含字段id,name,age,sex,height,weight,用name,age,height建立联合索引,并提供创建30个学生信息的sql,用来验证联合索引
CREATE TABLE tbl_student_info (id numeric(19) PRIMARY KEY,name VARCHAR(100) NOT NULL,age INTEGER NOT NULL,sex varvhar(4),height DECIMAL(4,1),weight DECIMAL(4,1)
);-- 创建联合索引
CREATE INDEX idx_name_age_height ON tbl_student_info (name, age, height);
创建一个自增队列,用来创建id
create sequence tbl_student_info_seq;
创建30条数据:
INSERT INTO tbl_student_info (id,name, age, sex, height, weight) VALUES (tbl_student_info_seq.nextval,'张三', 20, '男', 175.0, 65.0);
INSERT INTO tbl_student_info (id,name, age, sex, height, weight) VALUES (tbl_student_info_seq.nextval,'李四', 21, '女', 162.0, 52.0);
INSERT INTO tbl_student_info (id,name, age, sex, height, weight) VALUES (tbl_student_info_seq.nextval,'王五', 22, '男', 178.0, 70.0);
INSERT INTO tbl_student_info (id,name, age, sex, height, weight) VALUES (tbl_student_info_seq.nextval,'赵六', 19, '女', 165.0, 55.0);
INSERT INTO tbl_student_info (id,name, age, sex, height, weight) VALUES (tbl_student_info_seq.nextval,'周七', 23, '男', 180.0, 75.0);
INSERT INTO tbl_student_info (id,name, age, sex, height, weight) VALUES (tbl_student_info_seq.nextval,'吴八', 20, '女', 160.0, 50.0);
INSERT INTO tbl_student_info (id,name, age, sex, height, weight) VALUES (tbl_student_info_seq.nextval,'郑九', 21, '男', 176.0, 68.0);
INSERT INTO tbl_student_info (id,name, age, sex, height, weight) VALUES (tbl_student_info_seq.nextval,'孙十', 22, '女', 163.0, 53.0);
INSERT INTO tbl_student_info (id,name, age, sex, height, weight) VALUES (tbl_student_info_seq.nextval,'钱十一', 19, '男', 172.0, 63.0);
INSERT INTO tbl_student_info (id,name, age, sex, height, weight) VALUES (tbl_student_info_seq.nextval,'冯十二', 23, '女', 168.0, 57.0);INSERT INTO tbl_student_info (id,name, age, sex, height, weight) VALUES (tbl_student_info_seq.nextval,'陈十三', 20, '男', 177.0, 67.0);
INSERT INTO tbl_student_info (id,name, age, sex, height, weight) VALUES (tbl_student_info_seq.nextval,'沈十四', 21, '女', 161.0, 51.0);
INSERT INTO tbl_student_info (id,name, age, sex, height, weight) VALUES (tbl_student_info_seq.nextval,'韩十五', 22, '男', 179.0, 71.0);
INSERT INTO tbl_student_info (id,name, age, sex, height, weight) VALUES (tbl_student_info_seq.nextval,'杨十六', 19, '女', 164.0, 54.0);
INSERT INTO tbl_student_info (id,name, age, sex, height, weight) VALUES (tbl_student_info_seq.nextval,'周十七', 23, '男', 181.0, 76.0);
INSERT INTO tbl_student_info (id,name, age, sex, height, weight) VALUES (tbl_student_info_seq.nextval,'吴十八', 20, '女', 166.0, 56.0);
INSERT INTO tbl_student_info (id,name, age, sex, height, weight) VALUES (tbl_student_info_seq.nextval,'郑十九', 21, '男', 174.0, 66.0);
INSERT INTO tbl_student_info (id,name, age, sex, height, weight) VALUES (tbl_student_info_seq.nextval,'王二十', 22, '女', 167.0, 58.0);
INSERT INTO tbl_student_info (id,name, age, sex, height, weight) VALUES (tbl_student_info_seq.nextval,'赵二十一', 19, '男', 173.0, 64.0);
INSERT INTO tbl_student_info (id,name, age, sex, height, weight) VALUES (tbl_student_info_seq.nextval,'李二十二', 23, '女', 169.0, 59.0);INSERT INTO tbl_student_info (id,name, age, sex, height, weight) VALUES (tbl_student_info_seq.nextval,'刘二十三', 20, '男', 176.0, 69.0);
INSERT INTO tbl_student_info (id,name, age, sex, height, weight) VALUES (tbl_student_info_seq.nextval,'陈二十四', 21, '女', 162.0, 52.0);
INSERT INTO tbl_student_info (id,name, age, sex, height, weight) VALUES (tbl_student_info_seq.nextval,'杨二十五', 22, '男', 178.0, 72.0);
INSERT INTO tbl_student_info (id,name, age, sex, height, weight) VALUES (tbl_student_info_seq.nextval,'周二十六', 19, '女', 165.0, 55.0);
INSERT INTO tbl_student_info (id,name, age, sex, height, weight) VALUES (tbl_student_info_seq.nextval,'吴二十七', 23, '男', 180.0, 75.0);
INSERT INTO tbl_student_info (id,name, age, sex, height, weight) VALUES (tbl_student_info_seq.nextval,'郑二十八', 20, '女', 160.0, 50.0);
INSERT INTO tbl_student_info (id,name, age, sex, height, weight) VALUES (tbl_student_info_seq.nextval,'王二十九', 21, '男', 176.0, 68.0);
INSERT INTO tbl_student_info (id,name, age, sex, height, weight) VALUES (tbl_student_info_seq.nextval,'李三十', 22, '女', 163.0, 53.0);
验证联合索引
为了验证联合索引是否被正确使用,你可以执行一些查询,比如:
-- 查询1: 使用name, age和height
EXPLAIN (ANALYZE, BUFFERS)
SELECT * FROM tbl_student_info WHERE name='张三' AND age=20 AND height=165.0;-- 查询2: 使用name和age
EXPLAIN (ANALYZE, BUFFERS)
SELECT * FROM tbl_student_info WHERE name='李四' AND age=20;-- 查询3: 只使用name
EXPLAIN (ANALYZE, BUFFERS)
SELECT * FROM tbl_student_info WHERE name='王五';-- 查询4: 只使用height
EXPLAIN (ANALYZE, BUFFERS)
SELECT * FROM tbl_student_info WHERE height=165.0;
2024年7月12号