在数据库中,最重要的查询优化手段就是为字段加上索引,在PgSql中最主要的有三种索引,单一索引,覆盖索引和Hash索引,单一索引是指只对SELECT条件中的特定列添加索引,覆盖索引是指建立一个联合索引,这个索引中包含所有需要从表中SELECT出的列,Hash索引是指对WHERE条件中的列进行Hash存储来进行查询,下面通过建立两个表,一张是10w数据,一张是100w数据,分别通过建立不同的索引来比较它们的查询速度。
create table if not exists test_100000 (
id serial primary key,
name varchar(50),
password varchar(50),
description varchar(50)
)
create table if not exists test_1000000 (
id serial primary key,
name varchar(50),
password varchar(50),
description varchar(50)
)
测试数据基数约等于行数的情况下(IN语句中的数据量大小为20)
EXPLAIN ANALYSE SELECT id, name, password, description FROM test_100000 WHERE name IN (
SELECT name FROM test_1000000 LIMIT 20
);
EXPLAIN ANALYSE SELECT id, name, password, description FROM test_1000000 WHERE name IN (
SELECT name FROM test_1000000 LIMIT 20
);
100000数据: 39.729 ms
1000000数据:521.748 ms
在name列建立索引
CREATE INDEX index_name_100000 ON test_100000 (name);
CREATE INDEX index_name_1000000 ON test_1000000 (name);
100000数据: 0.866 ms
1000000数据:1.870 ms
CREATE INDEX index_name_id_password_description_100000 ON test_1000000(name, id, password, description);
CREATE INDEX index_name_id_password_description_1000000 ON test_1000000(name, id, password, description);
100000数据:0.350 ms
1000000数据:0.609 ms
CREATE INDEX hash_name_1000000 ON test_1000000 USING hash (name);
CREATE INDEX hash_name_1000000 ON test_1000000 USING hash (name);
100000数据:0.194 ms
1000000数据:0.157 ms
在使用hash索引的情况下查找效率与数据大小无关,使用普通的B树索引,数据量越大查找速度越慢。在同时使用B树索引的情况下,因为覆盖索引减少了检索数据时回表的步骤所以相应的磁盘IO次数也减少了,比单纯使用单列的索引要快。