@SovietPower
2022-05-01T15:03:37.000000Z
字数 20856
阅读 1674
DB
Database (数据库)
Tablespace (表空间)
pg_default: 默认用于存储用户表、索引、临时表等(../data/base)pg_global: 系统表(../data/global)Schema (模式)
schema_name.object_name。schema_name时,系统按search_path顺序查找(show search_path)search_path为"$user", public,则表示先找与当前用户名同名的schema,再找publicschema。创建表空间
可指定owner,其拥有该表空间的所有权限。
要指定的相对位置是相对安装目录下的位置var/lib/opengauss/data。可指定最大大小。
CREATE TABLESPACE tablespace_name [ OWNER user_name ]RELATIVE LOCATION 'directory' [ MAXSIZE 'space_size' ] [ with_option_clause ];
重命名表空间
ALTER TABL ESPACE tablespace_name RENAME TO new_tablespace_name;
修改表空间所有者
ALTER TABLESPACE tablespace_name OWNER TO new_owner;
修改表空间限额
ALTER TABL ESPACE tablespace_name RESIZE MAXSIZE { UNLIMITED I'space_size'};
删除表空间
删除前表空间中不能有任何数据库对象
DROP TABLESPACE [ IF EXISTS ] tablespace_name;
用指定名称创建模式
CREATE SCHEMA schema_name [ AUTHORIZATION user_name ] [ schema_element [...] ];
用用户名创建模式
CREATE SCHEMA AUTHORIZATION username [ schema_element [...] ];
修改模式的名称
ALTER SCHEMA schema_name RENAME TO new_name;
修改模式的所有者
ALTER SCHEMA schema_name OWNER TO new_owner;
删除模式
若该模式下有其它对象,CASCADE为全删掉;RESTRICT为不允许删除该模式。
DROP SCHEMA [IF EXISTS ] schema_name [, ...] [ CASCADE | RESTRICT ];
CREATE [UNIQUE] INDEX [ CONCURRENTLY ] [ [schema_name.]index_name ] ON table_name [ USING method ]({{ col_name | ( expression)} [COLLATE collation ][ opclass ][ ASC | DESC][ NULLS { FIRST | LAST}]}[,..])[WITH ( {storage_parameter = value}[,..])][ TABLESPACE tablespace_name ][ WHERE predicate ];
unique表示不允许该索引值有重复。CONCURRENTLY为并行创建。
method:
btree:类似于B+树hash:hash索引gin:倒排索引gist:适用于几何和地理等多维数据Psort:针对列存表进行局部排序索引ubtree:多版本B-tree索引
DROP INDEX [ CONCURRENTLY ] [ IF EXISTS ] index name [,..][ CASCADE | RESTRICT ];
查看索引:
select * from pg_indexes where [schemaname='...' and ] tablename='...';
首先运行之前创建的openGauss容器,连接数据库db2022。
PS H:\> docker exec -it opengauss3 bashroot@97375c3acbd1:/# su ommomm@97375c3acbd1:/$ gsql -d db2022 -r
db2022=# create tablespace myspace RELATIVE LOCATION 'tablespace/myspace';CREATE TABLESPACE
同时在该模式下创建数据表 mytable 和视图 myview。
db2022=# create schema myschema authorization gxbdb2022-# create table mytable (id int, value int, primary key (id))db2022-# create view myview as select * from public.takes;NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "mytable_pkey" for table "mytable"CREATE SCHEMA
记录每条语句返回的结果并解释其完成的操作
db2022=# show search_path;search_path----------------"$user", public(1 row)当前模式的search_pathdb2022=# insert into mytable values(1,100);ERROR: relation "mytable" does not exist on gaussdbLINE 1: insert into mytable values(1,100);之前创建的表位于 myschema,但当前 search_path 不包含 myschema,故不指定 myschema 则找不到该表。^db2022=# create table mytable (id int, value int, primary key (id));NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "mytable_pkey" for table "mytable"CREATE TABLE创建表 public.mytable。db2022=# insert into mytable values(1,100);INSERT 0 1search_path 包含 public,故可找到表 public.mytable。db2022=# insert into myschema.mytable values(1,100);INSERT 0 1指定模式,故可找到表 myschema.mytable。db2022=# SET search_path TO myschema,public;SET修改 search_path。db2022=# insert into mytable values(2,200);INSERT 0 1因为 myschema 包含该表,所以向表 myschema.mytable 中插入。db2022=# insert into myschema.mytable values(2,200);ERROR: duplicate key value violates unique constraint "mytable_pkey"DETAIL: Key (id)=(2) already exists.重复插入。此时 myschema.mytable 就是 mytable。db2022=# insert into public.mytable values(2,200);INSERT 0 1此时使用 public.mytable 需指定模式名 public。
记录每条语句返回的结果并解释其完成的操作
db2022=# create table takes (like public.takes) tablespace myspace;CREATE TABLE创建 myschema.takes,结构同之前的takes,使用自定义表空间。db2022=# insert into takes select * from public.takes;INSERT 0 30094导入之前的 takes 中的数据db2022=# select * from pg_indexes where schemaname='public' and tablename='takes';schemaname | tablename | indexname | tablespace | indexdef------------+-----------+------------+------------+-------------------------------------------------------------------------------------------------------------------public | takes | takes_pkey | | CREATE UNIQUE INDEX takes_pkey ON takes USING btree (id, course_id,sec_id, semester, year) TABLESPACE pg_default(1 row)之前的 takes 包含各字段上的 btree 索引db2022=# select * from pg_indexes where schemaname='myschema' and tablename='takes';schemaname | tablename | indexname | tablespace | indexdef------------+-----------+-----------+------------+----------(0 rows)新创建的 takes 不含索引db2022=# \timing onTiming is on.显示每一次 sql 执行所花的时间db2022=# select * from myschema.takes where id='79446' and course_id='748' and sec_id='1' and semester='Fall' and year=2003;id | course_id | sec_id | semester | year | grade-------+-----------+--------+----------+------+-------79446 | 748 | 1 | Fall | 2003 | A(1 row)Time: 99.561 msdb2022=# select * from public.takes where id='79446' and course_id='748' and sec_id='1' and semester='Fall' and year=2003;id | course_id | sec_id | semester | year | grade-------+-----------+--------+----------+------+-------79446 | 748 | 1 | Fall | 2003 | A(1 row)Time: 45.003 ms该单值查询中,有索引的表比无索引的表快1倍多
新建索引再次对比(在两个表中,后续的查询均比之前的查询快得多,可能是缓存了?但索引依旧有效)
db2022=# create unique index takes_pk on myschema.takes (id,course_id,sec_id,semester,year) tablespace myspace;CREATE INDEXTime: 411.531 ms在新表中也建相同的索引。db2022=# select * from myschema.takes where id='79446' and course_id='748' and sec_id='1' and semester='Fall' and year=2003;id | course_id | sec_id | semester | year | grade-------+-----------+--------+----------+------+-------79446 | 748 | 1 | Fall | 2003 | A(1 row)Time: 1.068 msdb2022=# select * from public.takes where id='79446' and course_id='748' and sec_id='1' and semester='Fall' and year=2003;id | course_id | sec_id | semester | year | grade-------+-----------+--------+----------+------+-------79446 | 748 | 1 | Fall | 2003 | A(1 row)Time: 1.008 ms此时两个表中查询时间基本一致。db2022=# drop index myschema.takes_pk;DROP INDEXTime: 239.175 ms删除索引db2022=# select * from myschema.takes where id='79446' and course_id='748' and sec_id='1' and semester='Fall' and year=2003;id | course_id | sec_id | semester | year | grade-------+-----------+--------+----------+------+-------79446 | 748 | 1 | Fall | 2003 | A(1 row)Time: 4.761 msdb2022=# select * from public.takes where id='79446' and course_id='748' and sec_id='1' and semester='Fall' and year=2003;id | course_id | sec_id | semester | year | grade-------+-----------+--------+----------+------+-------79446 | 748 | 1 | Fall | 2003 | A(1 row)Time: 0.885 ms删除索引后,两表间查询时间又有了明显差距
记录每条语句返回的结果并解释其完成的操作。
可能是电脑问题,用时浮动比较大。
无索引更新:
db2022=# insert into myschema.takes values ('00000','000','0','Fall',2022,'Z');INSERT 0 1Time: 208.899 ms
对每个属性建立btree索引:
用时为无索引的3到4倍。
db2022=# create index takes_1 on myschema.takes (id) tablespace myspace;CREATE INDEXTime: 567.284 msdb2022=# create index takes_2 on myschema.takes (course_id) tablespace myspace;CREATE INDEXTime: 347.021 msdb2022=# create index takes_3 on myschema.takes (sec_id) tablespace myspace;CREATE INDEXTime: 383.941 msdb2022=# create index takes_4 on myschema.takes (semester) tablespace myspace;CREATE INDEXTime: 453.346 msdb2022=# create index takes_5 on myschema.takes (year) tablespace myspace;CREATE INDEXTime: 787.605 msdb2022=# create index takes_6 on myschema.takes (grade) tablespace myspace;CREATE INDEXTime: 2343.505 msdb2022=# select * from pg_indexes where schemaname='myschema' and tablename='takes';schemaname | tablename | indexname | tablespace | indexdef------------+-----------+-----------+------------+--------------------------------------------------------------------------myschema | takes | takes_1 | myspace | CREATE INDEX takes_1 ON takes USING btree (id) TABLESPACE myspacemyschema | takes | takes_2 | myspace | CREATE INDEX takes_2 ON takes USING btree (course_id) TABLESPACE myspacemyschema | takes | takes_3 | myspace | CREATE INDEX takes_3 ON takes USING btree (sec_id) TABLESPACE myspacemyschema | takes | takes_4 | myspace | CREATE INDEX takes_4 ON takes USING btree (semester) TABLESPACE myspacemyschema | takes | takes_5 | myspace | CREATE INDEX takes_5 ON takes USING btree (year) TABLESPACE myspacemyschema | takes | takes_6 | myspace | CREATE INDEX takes_6 ON takes USING btree (grade) TABLESPACE myspace(6 rows)Time: 102.131 msdb2022=# insert into myschema.takes values ('11111','111','1','Fall',2022,'Z');INSERT 0 1Time: 5397.037 msdb2022=# delete myschema.takes where id='11111' and course_id='111';DELETE 1Time: 545.066 msdb2022=# insert into myschema.takes values ('11111','111','1','Fall',2022,'Z');INSERT 0 1Time: 290.331 ms删除之后重新插入会更快,可能也是缓存的问题?db2022=# insert into myschema.takes values ('11111','1110','1','Fall',2022,'Z');INSERT 0 1Time: 829.721 msdb2022=# insert into myschema.takes values ('11111','1120','1','Fall',2022,'Z');INSERT 0 1Time: 767.316 ms
对每个属性建立hash索引:
用时依旧为无索引的3到4倍。
db2022=# create index takes_7 on myschema.takes using hash (id) tablespace myspace;CREATE INDEXTime: 994.802 msdb2022=# create index takes_8 on myschema.takes using hash (course_id) tablespace myspace;CREATE INDEXTime: 675.056 msdb2022=# create index takes_9 on myschema.takes using hash (sec_id) tablespace myspace;CREATE INDEXTime: 624.564 msdb2022=# create index takes_10 on myschema.takes using hash (semester) tablespace myspace;CREATE INDEXTime: 639.372 msdb2022=# create index takes_11 on myschema.takes using hash (year) tablespace myspace;CREATE INDEXTime: 356.669 msdb2022=# create index takes_12 on myschema.takes using hash (grade) tablespace myspace;CREATE INDEXTime: 3122.687 msdb2022=# insert into myschema.takes values ('22222','222','2','Fall',2022,'Z');INSERT 0 1Time: 723.869 msdb2022=# insert into myschema.takes values ('22221','227','2','Fall',2022,'Z');INSERT 0 1Time: 845.770 ms
对每个属性建立hash索引:
用时依旧为无索引的3到4倍。
前几次 insert 用时浮动极大,不知道原因。
db2022=# create index takes_13 on myschema.takes (id,course_id) tablespace myspace;CREATE INDEXTime: 2344.680 msdb2022=# create index takes_14 on myschema.takes (course_id,sec_id) tablespace myspace;CREATE INDEXTime: 1309.072 msdb2022=# create index takes_15 on myschema.takes (sec_id,semester) tablespace myspace;CREATE INDEXTime: 1117.506 msdb2022=# create index takes_16 on myschema.takes (semester,year) tablespace myspace;CREATE INDEXTime: 1349.810 msdb2022=# create index takes_17 on myschema.takes (year,grade) tablespace myspace;CREATE INDEXTime: 625.121 msdb2022=# create index takes_18 on myschema.takes (grade,id) tablespace myspace;CREATE INDEXTime: 2183.103 msdb2022=# insert into myschema.takes values ('33333','333','3','Fall',2022,'Z');INSERT 0 1Time: 4466.036 msdb2022=# insert into myschema.takes values ('33444','355','4','Fall',2022,'Z');INSERT 0 1Time: 103.846 msdb2022=# insert into myschema.takes values ('44444','555','4','Fall',2022,'Z');INSERT 0 1Time: 378.363 msdb2022=# insert into myschema.takes values ('55555','555','4','Fall',2022,'Z');INSERT 0 1Time: 803.185 msdb2022=# insert into myschema.takes values ('66666','666','1','Fall',2022,'Z');INSERT 0 1Time: 836.411 msdb2022=# insert into myschema.takes values ('11166','116','3','Fall',2022,'Z');INSERT 0 1Time: 837.816 ms
db2022=# drop schema myschema;ERROR: cannot drop schema myschema because other objects depend on itDETAIL: table mytable depends on schema myschemaview myview depends on schema myschematable takes depends on schema myschemaHINT: Use DROP ... CASCADE to drop the dependent objects too.Time: 873.420 msdb2022=# drop tablespace myspace;ERROR: tablespace "myspace" is not emptyTime: 2811.570 msdb2022=# drop schema myschema CASCADE;NOTICE: drop cascades to 3 other objectsDETAIL: drop cascades to table mytabledrop cascades to view myviewdrop cascades to table takesDROP SCHEMATime: 1311.816 msdb2022=# drop tablespace myspace;DROP TABLESPACETime: 3746.748 msdb2022=# select count(*) from myschema.takes;ERROR: schema "myschema" does not existLINE 1: select count(*) from myschema.takes;^Time: 0.941 ms
测试维度
测试环境
db2022=# show server_version;server_version----------------9.2.4(1 row)db2022=# select version();version(openGauss 2.1.0 build 590b0f8e) compiled at 2021-09-30 14:29:04 commit 0 last mr on x86_64-unknown-linux-gnu, compiled by g++ (GCC) 7.3.0, 64-bit(1 row)
数据集
使用:prereq包含100条数据,takes包含约3w条数据,mytakes包含约100w条数据。
100条数据的不测了,比较麻烦,结论基本就是随数据集规模增长,索引查询优势会更大。
为方便删除index,使用新建的与takes相同的表takes1。
下面是mytakes的生成方式,会包含大量id或course_id相同的元组。
db2022=# create table mytakes (like takes);CREATE TABLETime: 5100.183 msdb2022=# insert into mytakes select * from takes;INSERT 0 30094Time: 1527.305 msdb2022=# create table takes1 (like takes);CREATE TABLETime: 1974.941 msdb2022=# insert into takes1 select * from takes;INSERT 0 30094Time: 466.372 msdb2022=# update takes1 set course_id = course_id||'x';UPDATE 30094Time: 334.094 msdb2022=# insert into mytakes select * from takes1;INSERT 0 30094Time: 2277.785 msdb2022=# delete takes1;DELETE 30094Time: 12980.146 msdb2022=# insert into takes1 select * from takes;INSERT 0 30094Time: 11817.119 msdb2022=# update takes1 set course_id = course_id||'y';UPDATE 30094Time: 13041.597 msdb2022=# insert into mytakes select * from takes1;INSERT 0 30094Time: 15906.420 msdb2022=# delete takes1db2022-# ;DELETE 30094Time: 18279.577 msdb2022=# insert into takes1 select * from mytakes;INSERT 0 90282db2022=# update takes1 set sec_id=sec_id||'a';UPDATE 90282db2022=# insert into mytakes select * from takes1;INSERT 0 90282Time: 36853.872 msdb2022=# update takes1 set sec_id=sec_id||'b';UPDATE 90282Time: 654.162 msdb2022=# insert into mytakes select * from takes1;INSERT 0 90282Time: 532.678 msdb2022=# delete takes1;DELETE 90282Time: 3595.527 msdb2022=# select count(*) from mytakes;count--------270846(1 row)Time: 50.027 msdb2022=# insert into takes1 select * from mytakes;INSERT 0 270846Time: 6825.950 msdb2022=# update takes1 set sec_id=sec_id||'c';UPDATE 270846db2022=# insert into mytakes select * from takes1;INSERT 0 270846db2022=# update takes1 set sec_id=sec_id||'d';UPDATE 270846db2022=# insert into mytakes select * from takes1;INSERT 0 270846db2022=# update takes1 set sec_id=sec_id||'e';UPDATE 270846db2022=# insert into mytakes select * from takes1;INSERT 0 270846db2022=# select count(*) from mytakes;count---------1083384(1 row)
3w条数据测试 等值查询
db2022=# select * from pg_indexes where tablename='takes1';schemaname | tablename | indexname | tablespace | indexdef------------+-----------+-----------+------------+----------(0 rows)Time: 2.366 msdb2022=# select * from takes1 where id='28361' and course_id='960' and sec_id='1';id | course_id | sec_id | semester | year | grade-------+-----------+--------+----------+------+-------28361 | 960 | 1 | Fall | 2009 | C+(1 row)Time: 65.290 msdb2022=# select * from takes1 where id='259' and course_id='692' and sec_id='1';id | course_id | sec_id | semester | year | grade-----+-----------+--------+----------+------+-------259 | 692 | 1 | Spring | 2010 | B-(1 row)Time: 67.276 ms
3w条数据测试 范围查询
db2022=# select * from takes1 where course_id='476';id | course_id | sec_id | semester | year | grade-------+-----------+--------+----------+------+-------44551 | 476 | 1 | Fall | 2010 | C-51008 | 476 | 1 | Fall | 2010 | B+...Time: 1076.589 msdb2022=# select * from takes1 where course_id='949';id | course_id | sec_id | semester | year | grade-------+-----------+--------+----------+------+-------49450 | 949 | 1 | Fall | 2007 | A-54728 | 949 | 1 | Fall | 2007 | C...Time: 887.121 ms
100w条数据测试 等值查询
db2022=# select * from mytakes where id='37339' and course_id='237y' and sec_id='1abc';id | course_id | sec_id | semester | year | grade-------+-----------+--------+----------+------+-------37339 | 237y | 1abc | Spring | 2008 | B(1 row)Time: 192.314 msdb2022=# select * from mytakes where id='37339' and course_id='237y' and sec_id='1abcd';id | course_id | sec_id | semester | year | grade-------+-----------+--------+----------+------+-------37339 | 237y | 1abcd | Spring | 2008 | B(1 row)Time: 193.495 ms
100w条数据测试 范围查询
db2022=# select * from mytakes where course_id='486y';id | course_id | sec_id | semester | year | grade-------+-----------+--------+----------+------+-------123 | 486y | 1 | Fall | 2009 | C827 | 486y | 1 | Fall | 2009 | B86573 | 486y | 1 | Fall | 2009 | B...Time: 1230.652 msdb2022=# select * from mytakes where course_id='704y';id | course_id | sec_id | semester | year | grade-------+-----------+--------+----------+------+-------55940 | 704y | 1 | Spring | 2008 | B-17128 | 704y | 1 | Spring | 2008 | C+60366 | 704y | 1 | Spring | 2008 | B...Time: 850.035 ms
3w条数据测试 等值查询
db2022=# create unique index takes1_pk on takes1 (id,course_id,sec_id,semester,year);CREATE INDEXTime: 446.259 msdb2022=# select * from pg_indexes where tablename='takes1';schemaname | tablename | indexname | tablespace | indexdef------------+-----------+-----------+------------+-------------------------------------------------------------------------------------------------------------------public | takes1 | takes1_pk | | CREATE UNIQUE INDEX takes1_pk ON takes1 USING btree (id, course_id, sec_id, semester, year) TABLESPACE pg_default(1 row)Time: 12.272 msdb2022=# select * from takes where id='28361' and course_id='960' and sec_id='1';id | course_id | sec_id | semester | year | grade-------+-----------+--------+----------+------+-------28361 | 960 | 1 | Fall | 2009 | C+(1 row)Time: 1.225 msdb2022=# select * from takes where id='259' and course_id='692' and sec_id='1';id | course_id | sec_id | semester | year | grade-----+-----------+--------+----------+------+-------259 | 692 | 1 | Spring | 2010 | B-(1 row)Time: 1.095 ms
3w条数据测试 范围查询
db2022=# select * from takes where course_id='476';id | course_id | sec_id | semester | year | grade-------+-----------+--------+----------+------+-------44551 | 476 | 1 | Fall | 2010 | C-51008 | 476 | 1 | Fall | 2010 | B+...Time: 290.466 msdb2022=# select * from takes where course_id='949';id | course_id | sec_id | semester | year | grade-------+-----------+--------+----------+------+-------49450 | 949 | 1 | Fall | 2007 | A-54728 | 949 | 1 | Fall | 2007 | C...Time: 200.423 ms
100w条数据测试 等值查询
db2022=# select * from pg_indexes where tablename='mytakes';schemaname | tablename | indexname | tablespace | indexdef------------+-----------+-----------+------------+----------(0 rows)Time: 3.418 msdb2022=# create unique index mytakes_pk on mytakes (id,course_id,sec_id,semester,year);CREATE INDEXTime: 11262.171 msdb2022=# select * from mytakes where id='37339' and course_id='237y' and sec_id='1abc';id | course_id | sec_id | semester | year | grade-------+-----------+--------+----------+------+-------37339 | 237y | 1abc | Spring | 2008 | B(1 row)Time: 1.326 msdb2022=# select * from mytakes where id='37339' and course_id='237y' and sec_id='1abcd';id | course_id | sec_id | semester | year | grade-------+-----------+--------+----------+------+-------37339 | 237y | 1abcd | Spring | 2008 | B(1 row)Time: 0.888 ms
100w条数据测试 范围查询
db2022=# select * from mytakes where course_id='486y';id | course_id | sec_id | semester | year | grade-------+-----------+--------+----------+------+-------123 | 486y | 1 | Fall | 2009 | C827 | 486y | 1 | Fall | 2009 | B86573 | 486y | 1 | Fall | 2009 | B...Time: 1238.876 msdb2022=# select * from mytakes where course_id='704y';id | course_id | sec_id | semester | year | grade-------+-----------+--------+----------+------+-------55940 | 704y | 1 | Spring | 2008 | B-17128 | 704y | 1 | Spring | 2008 | C+60366 | 704y | 1 | Spring | 2008 | B...Time: 779.980 ms
3w条数据测试 等值查询
db2022=# drop index takes1_pk;DROP INDEXTime: 824.120 msdb2022=# create index takes1_pk on takes1 (id,course_id,sec_id,semester,year);CREATE INDEXTime: 1577.301 msdb2022=# select * from pg_indexes where tablename='takes1';schemaname | tablename | indexname | tablespace | indexdef------------+-----------+-----------+------------+------------------------------------------------------------------------------------------------------------public | takes1 | takes1_pk | | CREATE INDEX takes1_pk ON takes1 USING btree (id, course_id, sec_id,semester, year) TABLESPACE pg_default(1 row)Time: 4.266 msdb2022=# select * from takes where id='28361' and course_id='960' and sec_id='1';id | course_id | sec_id | semester | year | grade-------+-----------+--------+----------+------+-------28361 | 960 | 1 | Fall | 2009 | C+(1 row)Time: 0.942 msdb2022=# select * from takes where id='259' and course_id='692' and sec_id='1';id | course_id | sec_id | semester | year | grade-----+-----------+--------+----------+------+-------259 | 692 | 1 | Spring | 2010 | B-(1 row)Time: 0.969 ms
3w条数据测试 范围查询
db2022=# select * from takes where course_id='476';id | course_id | sec_id | semester | year | grade-------+-----------+--------+----------+------+-------44551 | 476 | 1 | Fall | 2010 | C-51008 | 476 | 1 | Fall | 2010 | B+...Time: 321.893 msdb2022=# select * from takes where course_id='949';id | course_id | sec_id | semester | year | grade-------+-----------+--------+----------+------+-------49450 | 949 | 1 | Fall | 2007 | A-54728 | 949 | 1 | Fall | 2007 | C...Time: 351.266 ms
100w条数据测试 等值查询
db2022=# drop index mytakes_pk;DROP INDEXTime: 526.671 msdb2022=# select * from pg_indexes where tablename='mytakes';schemaname | tablename | indexname | tablespace | indexdef------------+-----------+-----------+------------+----------(0 rows)Time: 2.022 msdb2022=# create index mytakes_pk on mytakes (id,course_id,sec_id,semester,year);CREATE INDEXTime: 15270.766 msdb2022=# select * from mytakes where id='37339' and course_id='237y' and sec_id='1abc';id | course_id | sec_id | semester | year | grade-------+-----------+--------+----------+------+-------37339 | 237y | 1abc | Spring | 2008 | B(1 row)Time: 1.112 msdb2022=# select * frommytakes where id='37339' and course_id='237y' and sec_id='1abcd';id | course_id | sec_id | semester | year | grade-------+-----------+--------+----------+------+-------37339 | 237y | 1abcd | Spring | 2008 | B(1 row)Time: 0.926 ms
100w条数据测试 范围查询
db2022=# select * from mytakes where course_id='486y';id | course_id | sec_id | semester | year | grade-------+-----------+--------+----------+------+-------123 | 486y | 1 | Fall | 2009 | C827 | 486y | 1 | Fall | 2009 | B86573 | 486y | 1 | Fall | 2009 | B...Time: 999.292 msdb2022=# select * from mytakes where course_id='704y';id | course_id | sec_id | semester | year | grade-------+-----------+--------+----------+------+-------55940 | 704y | 1 | Spring | 2008 | B-17128 | 704y | 1 | Spring | 2008 | C+60366 | 704y | 1 | Spring | 2008 | B...Time: 774.836 ms
范围查询的用时与结果有关,取两次平均值。
因为结果比较简单,就不做图了。
3w数据集
| 查询方式 | 无索引 | 唯一索引 (无索引比例) | 非唯一索引 (无索引比例) |
|---|---|---|---|
| 等值查询 | 66 | 1.16 (1.76%) | 0.95 (1.44%) |
| 范围查询 | 981 | 245 (25.0%) | 336 (34.25%) |
100w数据集
| 查询方式 | 无索引 | 唯一索引 (无索引比例) | 非唯一索引 (无索引比例) |
|---|---|---|---|
| 等值查询 | 192 | 1.11 (0.58%) | 1.02 (0.53%) |
| 范围查询 | 1040 | 1010 (97.1%) | 887 (85.3%) |
结论
索引可大幅提高查询效率,但影响更新效率,且当结果集很大时,与无索引查询的差距会变小。
唯一索引和非唯一索引没有明显差别。
读取性能:
唯一索引:查到目标值后,即可停止查询,返回结果。
普通索引:查到目标值后,继续查找直至与目标值不相等时,停止查询,返回结果。
对比:每次查询,都将磁盘中的一个数据页读取到内存中,故即使唯一索引只查询一个值,也要读取整个数据页,所以两者读取性能相差不大。更新性能:
唯一索引:将数据页读入内存(因为要判断有没有冲突,故不能直接用 change buffer),更新数据。
普通索引:将更新的数据缓存到 change buffer 中,更新结束,后续执行vmerge。
对比:除了更新完后要立刻查询的操作,普通索引因为不需要读入内存,性能更优.
故一般更推荐用普通索引。