翻译自原文链接:
PostgreSQL Query: Introduction, Explanation, and 50 Examples
介绍一个SQL查询是怎么样的。
如何在PostgreSQL中使用SQL查询。
我将提供50个SQL查询的例子,一起来学习吧。
什么是SQL
SQL是
结构化查询语言
Structured Query Language
的缩写。 最初,它被称为
SEQUEL
(结构化英语查询语言),
用于存储和处理数据库中的数据
。 如今,SQL被广泛用于在关系数据库管理系统(RDBMS)中执行所有类型的数据操作。
SQL是一种功能强大的语言,我们可以在其中执行各种操作,如:
在数据库中插入,更新和删除记录(DML操作)
在数据库中创建新对象(DDL操作)
在表,过程,函数和视图上设置权限
还有更多...
什么是ANSI SQL标准?
美国国家标准协会(ANSI)
于1986年创建了SQL标准,并于1987年被国际标准化组织(ISO)采纳。要使每个RDBMS都符合ANSI标准,它们都必须用尽可能相似的命令支持一些主要的命令,例如DML。
SQL遵循
ANSI / ISO
标准,但是
不同的数据库系统使用不同版本的SQL语言
。例如,在PostgreSQL中,我们可以使用
RETURNING
子句执行
INSERT
操作,而并非所有其他数据库都能做到。
即使如此,不同的数据库系统需要符合ANSI标准,所有数据库都以相同的方式支持命令(如DELETE,UPDATE,SELECT,INSERT),也就是说,语法应在任何地方都可以使用。
以
INSERT
为例,它符合SQL的标准,不同之处在于
RETURNING
子句是PostgreSQL扩展,类似的还有:
在INSERT中使用WITH的能力。
以及在ON CONFLICT中指定替代动作的能力。
此外,标准不允许列名列表被省略,但PostgreSQL中不是所有的列都由VALUES子句或查询填充的情况。
SQL标准指定:只有id列存在的时候,
OVERRIDING SYSTEM VALUE
才可以被指定,但 PostgreSQL在任何情况下都允许该子句,如果不适用则将其忽略。
如果你想知道更多具体清晰的区别,可以查看PostgreSQL的文档。
50个例子
现在让我们学习探索一些常见实用的PostgreSQL的demo吧。
1. create table创建表
创建一个空表,由命令发起人拥有。
postgres=# create table dummy_table(name varchar(20),address text,age int);
CREATE TABLE
2. insert插入数据
向表中插入数据
postgres=# insert into dummy_table values('XYZ','location-A',25);
INSERT 0 1
postgres=# insert into dummy_table values('ABC','location-B',35);
INSERT 0 1
postgres=# insert into dummy_table values('DEF','location-C',40);
INSERT 0 1
postgres=# insert into dummy_table values('PQR','location-D',54);
INSERT 0 1
3. select查询,没有where子句
没有指定where条件,将会从数据库中获取所有的记录
postgres=# select * from dummy_table;
name | address | age
---------+--------------+ -----
XYZ | location-A | 25
ABC | location-B | 35
DEF | location-C | 40
PQR | location-D | 54
(4 rows)
4. udpate更新数据
将PQR
的年龄更新为50
postgres=# update dummy_table set age=50 where name='PQR';
UPDATE 1
postgres=# select * from dummy_table;
name | address | age
--------+--------------+-------
XYZ | location-A | 25
ABC | location-B | 35
DEF | location-C | 40
PQR | location-D | 50
(4 rows)
为地址为location-D
的人设置姓名和年龄
postgres=# update dummy_table set name='GHI',age=54 where address='location-D';
UPDATE 1
postgres=# select * from dummy_table;
name | address | age
------+------------+-----
XYZ | location-A | 25
ABC | location-B | 35
DEF | location-C | 40
GHI | location-D | 54
(4 rows)
postgres=#
如果我们要更新所有记录的address和age,我们不需要使用where子句。
postgres=# update dummy_table set age=54,address='location-X';
UPDATE 4
postgres=# select * from dummy_table ;
name | address | age
------+------------+--------
XYZ | location-X | 54
ABC | location-X | 54
DEF | location-X | 54
GHI | location-X | 54
(4 rows)
postgres=#
另外,可以使用RETURNING子句返回更新后的字段,建议在事务中执行该操作:BEGIN...COMMIT/ROLLBACK
。
postgres=# update dummy_table set age=30 where name='XYZ' returning age as age_no;
age_no
---------
(1 row)
UPDATE 1
5. delete删除数据
删除行,可以指定where也可没有,如果缺少where条件,将会删除所有行,并保留一个空表,以下示例删除年龄为65的行。
postgres=# delete from dummy_table where age=65;
DELETE 1
postgres=#
6. 比较符的运用
可以解决比较符号找到满足指定条件或值的列。
postgres=# select * from dummy_table where age <=50;
name | address | age
------+------------+-----
XYZ | location-A | 25
ABC | location-B | 35
DEF | location-C | 40
PQR | location-D | 50
(4 rows)
postgres=# select * from dummy_table where age>=50;
name | address | age
------+------------+-----
PQR | location-D | 50
(1 row)
postgres=# select * from dummy_table where age<>50;
name | address | age
------+------------+-----
XYZ | location-A | 25
ABC | location-B | 35
DEF | location-C | 40
(3 rows)
postgres=# select * from dummy_table where age=50;
name | address | age
------+------------+-----
PQR | location-D | 50
(1 row)
7.select distinct去重查询
返回不重复的值。
没有去重之前
postgres=# select age from dummy_table order by 1;
-----
(5 rows)
postgres=# select distinct age from dummy_table order by 1;
-----
(3 rows)
8. truncate清空表
清空一个表
postgres=# truncate table dummy_table;
TRUNCATE TABLE
9. drop 删除表
从数据库中移除这个表,包括该表的所有关联数据,索引,规则,触发器和约束。
postgresql=# drop table if exists dummy;
NOTICE: table "dummy" does not exist, skipping
DROP TABLE
10. create view 创建视图
生成视图【伪表】,从表、子集或从基础表中选择的列形成的虚拟表。
postgres=# create or replace view vi as select * from dummy_table where age is NULL;
CREATE VIEW
11. 使用select语句创建表
postgres=# select 'My name is X' as col1 , 10 as col2, 'Address is -XYZ location' as col3 into new_table;
SELECT 1
postgres=# select * from new_table ;
col1 | col2 | col3
---------------+------+--------------------------
My name is X | 10 | Address is -XYZ location
(1 row)
12. 设定超时
在GUC参数的帮助下,我们可以指定某个查询在特定的时间段后超时,中止,精确到毫秒。
postgresql=# set statement_timeout=10;
postgresql=# select pg_sleep(20);
ERROR: canceling statement due to statement timeout
13. 使用create sequence
该命令为序列号生成器,创建序列后,我们可以使用序列的nextval和currval函数将值插入表中。
postgres=# create sequence seq;
CREATE SEQUENCE
postgres=# create table tab(n int);
CREATE TABLE
postgres=# insert into tab values (nextval('seq'));
INSERT 0 1
postgres=# insert into tab values (currval('seq'));
INSERT 0 1
postgres=# insert into tab values (nextval('seq'));
INSERT 0 1
postgres=# select * from tab;
(3 rows)
14. 导入blob数据类型
PostgreSQL不直接支持BLOB(二进制大对象),但是我们可以使用以下方法使用:
假设你在/home/edb
文件夹中下载了PNG格式的图像。
[edb@localhost]$ ls /home/edb/mypic.png
/home/edb/mypic.png
如果你想将他存到postgreSQL中,进入postgreSQL安装的bin目录下,链接psql终端:
postgres=# Create table testing(n int,n1 oid);
CREATE TABLE
postgres=# insert into testing values (1,lo_import('/home/edb/mypic.png'));
INSERT 0 1
lo_import()
函数将命名文件加载到pg_largeobject
中,并返回一个将引用大对象的OID【Object identifier】值。选择表仅显示OID,而不显示组成这张照片的bits。
15. ilike不区分大小写
ILIKE
运算符是与LIKE
运算符相似的匹配函数,但具有不区分大小写的有点。
postgres=# select * from ted;
-----
(4 rows)
在where中使用ilike查询
postgres=# select * from ted where n ilike 'TAR%';
-----
(4 rows)
16. 层次化查询
层次查询是指结果具有结构化或父子关系并以树结构显示的查询。 若要查看分层查询的工作方式,需要创建一个虚拟表。
create table test_table(
emp_no int,
ename char(5),
job char(9),
manager_no int
向表中插入一些数据
insert into test_table values(10,'A1','CEO',null);
insert into test_table values(11, 'B1', 'VP', 10);
insert into test_table values(12, 'B2', 'VP', 10);
insert into test_table values(13, 'B3', 'VP', 10);
insert into test_table values(14, 'C1', 'DIRECTOR', 13);
insert into test_table values(15, ‘C2’, ‘DIRECTOR’, 13);
insert into test_table values(16, 'D1', 'MANAGER', 15);
insert into test_table values(17 ,'E1', 'ENGINEER', 11);
insert into test_table values(18, 'E2', 'ENGINEER', 11);
创建完成之后,就可以按照下面的方法去层次化查询了。
17. 计算长度的函数
返回指定字符串变量中的字符数或字节数。
postgres=# select name,age from dummy_table;
name | age
------+-----
XYZ | 25
ABC | 35
DEF | 40
PQR | 54
PQR |
(5 rows)
使用长度函数
postgres=# select length(name),length(age) from dummy_table;
length | length
--------+--------
3 | 2
3 | 2
3 | 2
3 | 2
(5 rows)
18. 发生has no destination for result data
如果我们收到了 query has no destination for result data
的异常消息,我们可以使用以下方法去避免。
postgres=# create or replace function f(n int)
returns int
begin
perform
now();
return 1;
$$ language 'plpgsql';
CREATE FUNCTION
postgresql=# select f(9);
(1 row)
在select into语句中使用变量
postgres=# create or replace function f(n int)
returns int
declare
a date;
begin
select now() into a;
raise notice ‘%s’,a;
return 1;
$$ language 'plpgsql';
CREATE FUNCTION
postgresql=# select f(9);
NOTICE: 24-SEP-20 13:15:46.23388s
(1 row)
19. 导出结果集
借助COPY命令,我们可以将数据从表导出到外部文本文件,也可以将数据从文本文件导入到表中。
导出结果集到text文件
postgres=# copy dummy_table to '/tmp/abc.txt';
COPY 5
postgres=# \! cat /tmp/abc.txt
XYZ location-A 25
ABC location-B 35
DEF location-C 40
PQR location-D 50
CXC 1 50
从text文件导入数据
postgres=# copy dummy_table from '/tmp/abc.txt';
COPY 5
20. 展示所有的数据库
postgres=# select oid,datname from pg_database;
oid | datname
-----------+-----------
13743 | postgres
1 | template1
13742 | template0
(3 rows)
我们还可以在psql prompt
下使用\l
命令列出所有的数据库名。
21. 检查语句执行时间
在psql promt
下使用\timing
指令开启。
postgres=# \timing
Timing is on.
现在查询之后就会显示执行时间了。
postgres=# select * from dummy_table;
name | address | age
------+------------+--------
XYZ | location-A | 25
ABC | location-B | 35
DEF | location-C | 40
PQR | location-D | 50
CXC | 1 | 50
(5 rows)
Time: 0.440 ms
postgres=#
22. 动态sql语句
在查询中,动态SQL用于减少重复性任务。
动态SQL查询不会缓存在内存中。
postgres=# do
postgres-# $$
postgres$# begin
postgres$# execute 'select * from dummy_table';
postgres$# end;
postgres$# $$;
23. count计数
返回表中的行数,如果使用count(*)
将包含null值,否则将排除。
postgres=# select count(*) from dummy_table;
count
-------
(1 row)
postgres=# select count(avg) from dummy_table;
count
-------
(1 row)
24. 分页 limit 和 offset
limit限制返回的记录数。
postgres=# select * from dummy_table limit 1;
name | address | age
------+------------+-----
XYZ | location-A | 25
(1 row)
offset用于跳过我们不需要的数据。
postgres=# select * from dummy_table offset 4;
name | address | age
------+---------+-----
cxc | 1 | 50
(1 row)
25. IF … ELSE 表达式
检查变量abc和xyz的值是否匹配,并显示结果,即150
postgres=# Do
Declare
abc int;
xyz int;
begin
abc:=100;
xyz:=abc;
if abc=xyz then
xyz=150;
raise notice '%',xyz;
end if;
NOTICE: 150
26. 使用join更新
如果我们要更新表X,但是需要基于另外一张表Y,我们可以按下面这样使用:
postgres=# create table X(n int, n1 char(10));
CREATE TABLE
postgres=# insert into X values (1,'abc');
INSERT 0 1
postgres=# insert into X values (2,'xyz');
INSERT 0 1
postgres=# insert into X values (3,'pqr');
INSERT 0 1
postgres=# create table Y(n int, n1 char(10));
CREATE TABLE
postgres=# insert into Y values (1,'');
INSERT 0 1
postgres=# insert into Y values (2,'');
INSERT 0 1
postgres=# insert into Y values (5,'axyz');
INSERT 0 1
postgres=# update Y set n1=X.n1 from X where X.n=Y.n;
UPDATE 2
postgres=# select * from Y;
n | n1
---+------------
5 | axyz
1 | abc
2 | xyz
(3 rows)
postgres=#
27. inner join
将从两个(或多个)表中查找表中指定列数据匹配的行
postgres=# select * from x inner join y on x.n1 = y.n1;
n | n1 | n | n1
---+------------+---+------------
1 | abc | 1 | abc
2 | xyz | 2 | xyz
(2 rows)
postgres=#
28. case表达式
CASE表达式是通用条件表达式,类似于IF…ELSE语句。
postgres=# SELECT age,
CASE age WHEN 25 THEN 'one'
WHEN 50 THEN 'two'
ELSE 'other'
FROM dummy_table;
age | case
-----+-------
25 | one
35 | other
40 | other
50 | two
50 | two
(5 rows)
29. 递归查询
递归查询用于处理层次查询或树状数据,下面创建测试数据:
CREATE TABLE emp_test (
id int,
ename varchar(255),
emanager int
INSERT INTO emp_test VALUES (1, 'abc', null);
INSERT INTO emp_test VALUES (2, 'xyz', 1);
INSERT INTO emp_test VALUES (3, 'def', 2);
INSERT INTO emp_test VALUES (4, 'cde', 1);
INSERT INTO emp_test VALUES (5, 'qrs', 2);
INSERT INTO emp_test VALUES (9, 'iop', 3);
INSERT INTO emp_test VALUES (10, 'klm', 4);
递归查询如下:
postgres=#WITH RECURSIVE emp_testnew AS (
SELECT id, ename, emanager
FROM emp_test
WHERE id = 2
UNION ALL
SELECT e.id, e.ename, e.emanager
FROM emp_test e
INNER JOIN emp_testnew e1 ON e1.id = e.emanager
SELECT *
FROM emp_testnew;
id | ename | emanager
----+-------+----------
2 | xyz | 1
3 | def | 2
5 | qrs | 2
9 | iop | 3
(4 rows)
postgres=#
30. log查询
使用pg_stat_statements模块,我们可以跟踪所有SQL语句的执行统计信息。 为此,我们需要创建一个扩展并在postgresql.conf文件内添加shared_preload_libraries
postgres=# create extension pg_stat_statements;
CREATE EXTENSION
postgres=# show shared_preload_libraries ;
shared_preload_libraries
-------------------------------------------------
$libdir/pg_stat_statements
(1 row)
postgres=# select query from pg_stat_statements where query like 'create table%';
-[ RECORD 1 ]-------------------
query | create table test(n int)
我们还可以通过启用postgresql.conf文件中的以下参数来配置PostgreSQL以生成日志输出
logging_collector = on
log_directory = 'log'
log_filename = ‘postgresql-%Y-%m-%d_%H%M%S.log'
log_destination = ‘stderr’
Log file will be created under the pg_log directory which resides under the data folder.
[centos@tushar-ldap-docker bin]$ ls data/log
postgresql-2020-09-17_150932.log postgresql-2020-09-19_000000.log
[centos@tushar-ldap-docker bin]$
查询记录的日志将被记录在这些文件中。
31. 使用变量
我们可以在psql prompt
下使用声明变量:
postgres=# \set cond 50
在where条件中使用变量
postgres=# select * from dummy_table where age=:cond;
name | address | age
------+------------+-----
PQR | location-D | 50
(1 row)
postgres=# \set cond 50
postgres=# select :cond+100 ;
?column?
----------
(1 row)
32. 日期查询
详细:https://www.postgresql.org/docs/12/functions-datetime.html
postgres=# select now();
----------------------------------
22-SEP-20 03:08:42.636385 +05:30
(1 row)
postgres=# select current_date;
current_date
--------------
22-SEP-20
(1 row)
postgres=# select current_time;
current_time
-----------------------
03:08:53.648466+05:30
(1 row)
我们还可以执行日期范围查询来查找值在两个时间戳之间的行:
postgres=# create table datetable(n int,n1 date);
CREATE TABLE
postgres=# insert into datetable values (1,'12-01-1980');
INSERT 0 1
postgres=# insert into datetable values (2,'12-01-2020');
INSERT 0 1
postgres=# insert into datetable values (3,'12-01-2000');
INSERT 0 1
postgres=# select * from datetable where n1 between '12-01-1980' and '12-01-2000';
n | n1
---+--------------------
1 | 12-JAN-80 00:00:00
3 | 12-JAN-00 00:00:00
(2 rows)
33. return query
当声明一个PL / pgSQL函数返回某个数据类型的SETOF时,该返回由RETURN QUERY命令指定
postgres=# CREATE FUNCTION get(int) RETURNS SETOF integer AS
$BODY$
BEGIN
RETURN QUERY SELECT age
FROM dummy_table
WHERE age >= $1 ;
RETURN;
$BODY$
LANGUAGE plpgsql;
postgres=# select * from get(9);
-----
(4 rows)
34. 并行查询
PostgreSQL中的并行查询使您可以利用许多CPU更快地完成查询。 这些GUC参数在postgresql.conf文件中设置
#max_parallel_maintenance_workers = 2 # taken from max_parallel_workers
#max_parallel_workers_per_gather = 2 # taken from max_parallel_workers
#parallel_leader_participation = on
#max_parallel_workers = 8 # maximum number of max_worker_processes that
# can be used in parallel operations
postgres=# create table ty(n int);
CREATE TABLE
postgres=# insert into ty values (generate_series(1,300000));
INSERT 0 300000
postgres=# analyze ty;
ANALYZE
postgres=# explain select * from ty where n<=1;
QUERY PLAN
---------------------------------------------------------------------
Gather (cost=1000.00..4536.88 rows=30 width=4)
Workers Planned: 1
-> Parallel Seq Scan on ty (cost=0.00..3533.88 rows=18 width=4)
Filter: (n <= 1)
(4 rows)
postgres=#
35. 逻辑运算符
postgreSQL中有三个主要的逻辑运算符:AND OR NOT。
AND = when both boolean expressions are true then it will return TRUE
OR = when any boolean expression is true then it will return TRUE
NOT = reverses the value of Boolean operator
36. 捕获重复的行
下面这个查询有两个重复的50:
postgres=# select age from dummy_table;
-----
(5 rows)
我们可以利用select ... having
来找到重复的行。
postgres=# select age, count(age) from dummy_table group by age having count(age)>1;
age | count
-----+-------
50 | 2
(1 row)
37. 枚举
枚举类型是包含静态的,有序的一组值的数据类型。
postgres=# CREATE TYPE mood AS ENUM ('sad', 'ok', 'happy');
CREATE TYPE
postgres=# create table testi(n int, n1 mood);
CREATE TABLE
postgres=# insert into testi values (1,'happy');
INSERT 0 1
postgres=# insert into testi values (1,'sad');
INSERT 0 1
postgres=# insert into testi values (1,'ok');
INSERT 0 1
如果enum没有被指定,将会报错:
postgres=# insert into testi values (1,'happyo');
ERROR: invalid input value for enum mood: "happyo"
38. pivot table
是一种通过将数据组织成更易于管理的格式来分析大量数据的有用方法。
CREATE TABLE newtb(id SERIAL, rowid varchar(10), attri varchar(10), val varchar(10));
INSERT INTO newtb(rowid, attri, val) values('t1','a1','v1');
INSERT INTO newtb(rowid, attri, val) values('t1','a2','v2');
INSERT INTO newtb(rowid, attri, val) values('t1','a3','v3');
INSERT INTO newtb(rowid, attri, val) values('t1','a4','v4');
INSERT INTO newtb(rowid, attri, val) values('t2','a1','v5');
INSERT INTO newtb(rowid, attri, val) values('t2','a2','v6');
INSERT INTO newtb(rowid, attri, val) values('t2','a3','v7');
INSERT INTO newtb(rowid, attri, val) values('t2','a4','v8');
创建pivot table,你需要安装 tablefunc extension:
postgres=# create extension tablefunc;
CREATE EXTENSION
Select *
FROM crosstab(
'select rowid, attri, val
from newtb
where attri = ''a2'' or attri = ''a3''
order by 1,2')
AS newtb(row_name varchar(10), category_1 varchar(10), category_2 varchar(10), category_3 varchar(10));
row_name | category_1 | category_2 | category_3
----------+------------+------------+--------------------------
t1 | v2 | v3 |
t2 | v6 | v7 |
(2 rows)
39. self join自连接
当我们针对自身联接表时,这称为自联接。 可以使用INNER JOIN
或LEFT JOIN
完成。 当比较同一表中的行时,自连接非常有用。
postgres=# create table emp1(emp_id int, firstname char(10), lastname char(10) , manager_id int);
CREATE TABLE
postgres=#
postgres=#
postgres=# insert into emp1 values(1,'ABC','XYZ',NULL);
INSERT 0 1
postgres=# insert into emp1 values(2,'TYU','BGV',1);
INSERT 0 1
postgres=# insert into emp1 values(3,'TEU','ZZV',1);
INSERT 0 1
postgres=# insert into emp1 values(4,'REU','AZV',2);
INSERT 0 1
postgres=# insert into emp1 values(5,'QREU','WZV',2);
INSERT 0 1
postgres=# insert into emp1 values(6,'DREU','QZV',3);
INSERT 0 1
postgres=# select a.firstname,b.lastname from emp1 a inner join emp1 b on a.emp_id=b.manager_id order by 1 ;
firstname | lastname
------------+------------
ABC | ZZV
ABC | BGV
TEU | QZV
TYU | WZV
TYU | AZV
(5 rows)
postgres=#
40. 父子递归
依靠 common table expressions (CTE),我们可以进行父子查询。
postgres=# CREATE TABLE recu_pc (
id SERIAL PRIMARY KEY,
name varchar(10) NOT NULL,
parent_id integer );
CREATE TABLE
postgres=# insert into recu_pc values (1, 'Grandmother', NULL);
INSERT 0 1
postgres=# insert into recu_pc values (2, 'mother', 1);
INSERT 0 1
postgres=# insert into recu_pc values (3, 'daughter', 2);
INSERT 0 1
postgres=# WITH RECURSIVE rec_q (id) as
SELECT recu_pc.id, recu_pc.name from recu_pc where name='mother'
UNION ALL
SELECT recu_pc.id, recu_pc.name from rec_q, recu_pc where recu_pc.parent_id = rec_q.id
SELECT *
FROM rec_q;
id | name
----+----------
2 | mother
3 | daughter
(2 rows)
41. 定义变量
使用匿名块 anonymous block,我们可以定义传入query的变量
postgres=# do
declare
a int;
begin
select age into a from dummy_table
where name ='XYZ';
raise notice '%',a;
NOTICE: 25
42. prepare语句
用于优化性能。 当执行PREPARE语句时,不仅会对其进行解析,而且还会对其进行分析,并且当我们执行EXECUTE命令时,将计划并执行准备好的语句。
postgres=# prepare test(int) as
select * from dummy_table where age=$1;
PREPARE
postgres=# execute test(50);
name | address | age
------+------------+---------
PQR | location-D | 50
CXC | 1 | 50
(2 rows)
43. 检查null值
postgres=# select * from dummy_table;
name | address | age
------+------------+-----
XYZ | location-A | 25
ABC | location-B | 35
DEF | location-C | 40
PQR | location-D | 54
PQR | location-D |
(5 rows)
找到age值为null的记录
postgres=# select name from dummy_table where age is null;
------
(1 row)
44. 使用exists检查查询是否为空
我们可以使用EXISTS检查查询是否为空。 EXISTS是一个布尔运算符,用于测试子查询中行的存在。
postgres=# select exists(select * from (select 'true' where 1=3));
exists
--------
(1 row)
postgres=# select exists(select * from (select 'true' where 1=1));
exists
--------
(1 row)
45. 语句执行时间日志
要查看查询的执行时间日志,您需要启用相关的GUC参数:
postgresql=# set log_min_duration_statement=0;
postgresql=# set log_statement='all';
现在,如果我们检查在data / log文件夹中创建的日志文件,我们应该会收到执行时间消息
2020-09-23 02:47:12.887 +0530 [30737] LOG: statement: create table gg1(n int);
2020-09-23 02:47:12.888 +0530 [30737] LOG: duration: 1.165 ms
2020-09-23 02:47:28.092 +0530 [30737] LOG: statement: insert into gg1 values (generate_series(1,100000));
2020-09-23 02:47:28.182 +0530 [30737] LOG: duration: 94.858 ms
46. 在shell脚本中执行查询
我们可以使用bash shell脚本执行psql命令。 下面的示例是一个print.sh文件,我们在其中执行两个数字的加法运算
[edb@tushar-ldap-docker misc]$ cat print.sh
#!/bin/bash
# This script is used to print addition of 2 numbers
# 1. Get path of bin directory.
BIN_DIRECTORY='/usr/psql-11/bin/'
$BIN_DIRECTORY/psql -U postgres -p 5432 -d postgres -c 'select 5+5;'
edb@tushar-ldap-docker misc]$ print.sh
?column?
----------
(1 row)
47. union操作符
用于合并两个或多个SQL语句的结果,同时消除重复的行。
postgres=# create table tab1(n int);
CREATE TABLE
postgres=# insert into tab1 values (1),(2);
INSERT 0 2
postgres=# create table tab2(n int);
CREATE TABLE
postgres=# insert into tab2 values (3),(2);
INSERT 0 2
postgres=# select * from tab1 union select * from tab2;
(3 rows)
48. 查询优化的命令
explain
explain命令显示一条语句的执行计划。 在explain计划中添加analyze关键字将执行查询并显示真实的行数和真实的运行时间。
vacuum
vacuum命令基本上删除所有由update删除或过时但未从表中物理删除的元组。
analyze
analyze收集有关数据库中表内容的统计信息
Database indexes
创建数据库索引可以避免全表扫描。
PostgreSQL configuration parameters
我们可能会使用某些PostgreSQL配置参数来获得更好的性能,例如max_connections
,checkpoint_segments
,work_mem和random_page_cost
。
49. alter table添加或修改列
添加或修改列
postgres=# alter table dummy_table add col1 int;
ALTER TABLE
postgres=# alter table dummy_table rename col1 to col2;
ALTER TABLE
postgres=# alter table dummy_table alter column col2 type char;
ALTER TABLE
postgres=# alter table dummy_table drop column col2;
ALTER TABLE
使用comment语句提供有关数据库对象的注释
postgres=# Comment on table dummy_table is 'This was a testing table';
COMMENT
postgres=# Comment on function f is 'Don''t update the function please' ;
COMMENT