提交 cb34344a 编写于 作者: M Mars Liu

transaction

上级 3e4651af
......@@ -8,7 +8,7 @@ create table orders (
item_id int,
amount int,
unit_price decimal(12, 4),
total_price decimal(12, 4)
price decimal(12, 4)
);
```
......@@ -22,7 +22,7 @@ create table orders (
item_id int,
amount int,
unit_price decimal(12, 4),
total_price decimal(12, 4),
price decimal(12, 4),
ts timestamp default now()
);
```
......@@ -37,7 +37,7 @@ create table orders (
item_id int,
amount int,
unit_price decimal(12, 4),
total_price decimal(12, 4),
price decimal(12, 4),
ts varchar(16) default now()
);
```
......@@ -50,7 +50,7 @@ create table orders (
item_id int,
amount int,
unit_price decimal(12, 4),
total_price decimal(12, 4),
price decimal(12, 4),
ts varchar(16) format 'yyyy-mm-dd'
);
```
......@@ -63,7 +63,7 @@ create table orders (
item_id int,
amount int,
unit_price decimal(12, 4),
total_price decimal(12, 4),
price decimal(12, 4),
ts date default now()
);
```
......@@ -76,7 +76,7 @@ create table orders (
item_id int,
amount int,
unit_price decimal(12, 4),
total_price decimal(12, 4),
price decimal(12, 4),
ts datetime default now()
);
```
......@@ -8,7 +8,7 @@ create table orders (
item_id int,
amount int,
unit_price decimal(12, 4),
total_price decimal(12, 4),
price decimal(12, 4),
ts timestamp default now()
);
```
......@@ -23,7 +23,7 @@ create table orders (
item_id int,
amount int,
unit_price decimal(12, 4),
total_price decimal(12, 4),
price decimal(12, 4),
description varchar(2000),
ts timestamp default now()
);
......@@ -39,7 +39,7 @@ create table orders (
item_id int,
amount int,
unit_price decimal(12, 4),
total_price decimal(12, 4),
price decimal(12, 4),
description char(2000),
ts timestamp default now()
);
......@@ -53,7 +53,7 @@ create table orders (
item_id int,
amount int,
unit_price decimal(12, 4),
total_price decimal(12, 4),
price decimal(12, 4),
description varchar(256) default '',
ts timestamp default now()
);
......@@ -67,7 +67,7 @@ create table orders (
item_id int,
amount int,
unit_price decimal(12, 4),
total_price decimal(12, 4),
price decimal(12, 4),
description text(2000),
ts timestamp default now()
);
......@@ -81,7 +81,7 @@ create table orders (
item_id int,
amount int,
unit_price decimal(12, 4),
total_price decimal(12, 4),
price decimal(12, 4),
description tinytext(2000),
ts timestamp default now()
);
......
......@@ -8,7 +8,7 @@ create table orders (
item_id int,
amount int,
unit_price decimal(12, 4),
total_price decimal(12, 4),
price decimal(12, 4),
description varchar(2000),
ts timestamp default now()
);
......@@ -24,7 +24,7 @@ create table orders (
item_id int,
amount int,
unit_price decimal(12, 4),
total_price decimal(12, 4),
price decimal(12, 4),
description varchar(2000),
picture blob,
ts timestamp default now()
......@@ -41,7 +41,7 @@ create table orders (
item_id int,
amount int,
unit_price decimal(12, 4),
total_price decimal(12, 4),
price decimal(12, 4),
description varchar(2000),
picture varchar(100000),
ts timestamp default now()
......@@ -56,7 +56,7 @@ create table orders (
item_id int,
amount int,
unit_price decimal(12, 4),
total_price decimal(12, 4),
price decimal(12, 4),
description varchar(2000),
picture text,
ts timestamp default now()
......@@ -71,7 +71,7 @@ create table orders (
item_id int,
amount int,
unit_price decimal(12, 4),
total_price decimal(12, 4),
price decimal(12, 4),
description varchar(2000),
picture binary(100000),
ts timestamp default now()
......@@ -86,7 +86,7 @@ create table orders (
item_id int,
amount int,
unit_price decimal(12, 4),
total_price decimal(12, 4),
price decimal(12, 4),
description varchar(2000),
picture varbinary(100000),
ts timestamp default now()
......
......@@ -8,7 +8,7 @@ create table orders (
item_id int,
amount int,
unit_price decimal(12, 4),
total_price decimal(12, 4),
price decimal(12, 4),
description varchar(2000),
ts timestamp default now(),
deal bool default false
......@@ -57,7 +57,7 @@ create table if not exists orders (
item_id int,
amount int,
unit_price decimal(12, 4),
total_price decimal(12, 4),
price decimal(12, 4),
description varchar(2000),
ts timestamp default now(),
deal bool default false
......
......@@ -9,7 +9,7 @@ create table orders
item_id int,
amount int,
unit_price decimal(12, 4),
total_price decimal(12, 4),
price decimal(12, 4),
description varchar(2000),
ts timestamp default now(),
deal bool default false
......
......@@ -2,18 +2,17 @@
SmartMarket 公司的OA数据库中包含以下结构:
```postgresql
```mysql
create table employee(
id serial primary key ,
name text,
dept text,
salary money,
meta jsonb default '{}'::jsonb
name varchar(256),
dept varchar(256),
salary decimal(12, 4)
);
create table budget(
id serial primary key ,
dept text,
dept varchar(256),
amount money
)
```
......
......@@ -2,7 +2,9 @@
"node_id": "mysql-ac3c072bc54749bdb82324f2b203890d",
"keywords": [],
"children": [],
"export": [],
"export": [
"count.json"
],
"keywords_must": [],
"keywords_forbid": [],
"group": 0
......
{
"type": "code_options",
"author": "ccat",
"source": "daily_payment_2.md",
"source": "count.md",
"notebook_enable": false,
"exercise_id": "ffde3c073ee848a093c5edc733c7a61c"
"exercise_id": "550bc91b4d7849ef8463a807871d145c"
}
\ No newline at end of file
# count 练习
Joe 建立了一个名为items的表
```
mysql> select * from items;
+----+-----------+
| id | item |
+----+-----------+
| 1 | 2 |
| 2 | NULL |
| 3 | 9 |
| 4 | 534214123 |
+----+-----------+
```
当他执行
```mysql
select count(*), count(item) from items;
```
会得到什么结果?
## 答案
```
3, 4
```
## 选项
### A
```
4, NULL
```
### B
```
3, 3
```
### C
```
1, 0
```
### D
```
NULL, NULL
```
### E
```
4, 4
```
\ No newline at end of file
......@@ -2,7 +2,9 @@
"node_id": "mysql-c5654c150993418a96f692496837fbb7",
"keywords": [],
"children": [],
"export": [],
"export": [
"sum.json"
],
"keywords_must": [],
"keywords_forbid": [],
"group": 0
......
{
"type": "code_options",
"author": "ccat",
"source": "sum.md",
"notebook_enable": false,
"exercise_id": "6ac9bb99a6684023ad80fde36ea32f6a"
}
\ No newline at end of file
# 求和练习
Joe 想要得到 orders 表
```mysql
create table orders (
id int primary key auto_increment,
item_id int,
amount int,
unit_price decimal(12, 4),
total decimal(12, 4),
description varchar(2000),
ts timestamp default now(),
deal bool default false
);
```
中所有单价(unit_price)超过 1000 的订单中,已成交(deal 为 true)的总值(total),这个查询应该是:
## 答案
```mysql
select sum(total) from orders where deal and unit_price > 1000;
```
## 选项
### A
```mysql
select sum(total) from orders where deal and unit_price > 1000;
```
### B
```mysql
select sum(total) from orders having deal and unit_price > 1000;
```
### C
```mysql
select sum(total) from orders group by deal having unit_price > 1000;
```
### D
```mysql
select sum(total) from orders having deal and unit_price > 1000;
```
\ No newline at end of file
......@@ -2,7 +2,9 @@
"node_id": "mysql-c1652108441c424197c0c3c526e4831c",
"keywords": [],
"children": [],
"export": [],
"export": [
"min.json"
],
"keywords_must": [],
"keywords_forbid": [],
"group": 0
......
{
"type": "code_options",
"author": "ccat",
"source": "min.md",
"notebook_enable": false,
"exercise_id": "c25658691a9043eab38b61aec9ad827c"
}
\ No newline at end of file
# 最小值练习
Joe 想要得到 employee 表
```mysql
create table employee
(
id serial primary key,
name varchar(256),
dept varchar(256),
salary decimal(12, 4)
);
```
中每个部门工资最低的员工的工资信息,这条查询应该怎么写?
## 答案
```mysql
select dept, min(salary) from employee group by dept;
```
## 选项
### A
```mysql
select dept, min(salary) from employee;
```
### B
```mysql
select dept, min(salary) from employee;
```
### C
```mysql
select dept, min(salary) from employee;
```
### D
```mysql
select sum(total) from orders having deal and unit_price > 1000;
```
\ No newline at end of file
......@@ -2,7 +2,9 @@
"node_id": "mysql-77042376726743bea5c97e82a67a2016",
"keywords": [],
"children": [],
"export": [],
"export": [
"max.json"
],
"keywords_must": [],
"keywords_forbid": [],
"group": 0
......
{
"type": "code_options",
"author": "ccat",
"source": "max.md",
"notebook_enable": false,
"exercise_id": "7e56c3165ccc46f5b2ffb3d0eba53eff"
}
\ No newline at end of file
# 最大值练习
利用员工信息表:
```mysql
create table employee
(
id serial primary key,
name varchar(256),
dept varchar(256),
salary decimal(12, 4)
);
```
Joe 做了一些关于 max 函数的练习,其中不正确的是:
## 答案
```mysql
select id, dept, max(salary) as salary, name
from employee
group by dept
```
可以得到每个部门工资最高的员工的全部信息。
## 选项
### A
```mysql
select dept, max(salary) as salary
from employee
group by dept
```
可以得到每个部门的最高工资。
### B
```mysql
select max(salary) as salary
from employee
```
可以得到全部员工中最高的工资。
### C
```mysql
select dept, sum(salary)
from employee
group by dept
having max(salary) < 20000
```
可以得到员工最高工资不超过两万的部门及其总的工资开支
### D
```mysql
select dept, min(salary)
from employee
group by dept
having max(salary) > 50000
```
可以得到员工最高工资超过五万的部门,及其最低工资的清单
......@@ -2,12 +2,12 @@
现有员工信息表如下:
```postgresql
```mysql
create table employee
(
id serial primary key,
name text,
dept text,
name varchar(256),
dept varchar(256),
salary money
);
```
......@@ -16,7 +16,7 @@ create table employee
## 答案
```postgresql
```mysql
select l.id, l.name, l.dept, l.salary
from employee as l
join (select max(salary) as salary, dept
......@@ -29,7 +29,7 @@ from employee as l
### select 与 group by 不匹配
```postgresql
```mysql
select id, name, dept, max(salary)
from employee
group by dept;
......@@ -37,7 +37,7 @@ group by dept;
### group by 不对
```postgresql
```mysql
select id, name, dept, max(salary)
from employee
group by dept, id, name;
......@@ -45,7 +45,7 @@ group by dept, id, name;
### group by 不对
```postgresql
```mysql
select id, name, dept, max(salary)
from employee
group by dept, id, name
......@@ -54,7 +54,7 @@ having salary = max(salary);
### 结构错误
```postgresql
```mysql
select id, name, dept, max(salary)
from employee
where salary = max(salary)
......
# 客户和订单
我们现在看下面这个客户/订单系统
Goods 中有客户/订单系统如下:
```postgresql
```mysql
create table customers
(
id serial primary key,
company_name text,
address text,
city text,
state text
company_name varchar(256),
address varchar(1024),
city varchar(256),
state varchar(256)
);
create table products
(
id serial primary key,
description text,
unit_price money
description varchar(1024),
unit_price decimal(12, 4)
);
create table orders
......
{
"node_id": "mysql-f045eeff32bd449c83afc76abdd65344",
"keywords": [],
"children": [],
"export": [
"subquery.json"
],
"keywords_must": [],
"keywords_forbid": []
}
\ No newline at end of file
# 子查询
现有员工表
```mysql
create table employee
(
id serial primary key,
name varchar(256),
dept varchar(256),
salary decimal(12, 4)
);
```
Joe 希望找出比销售部(dept 为 sale)工资最高的员工工资更高的那部分人,查询出他们的完整信息,下面哪一项可以满足要求?
## 答案
```mysql
select id, name, dept, salary
from employee
where salary > (select max(salary)
from employee
where dept = 'sale')
```
## 选项
### A
```mysql
select id, name, dept, salary
from employee
where dept = 'sale'
group by dept
having salary > max(salary)
```
### B
```mysql
select l.id, l.name, l.dept, l.salary
from employee as l
join employee as r on l.salary > max(r.salary)
where r.dept = 'sale'
group by r.dept
```
### C
```mysql
select id, name, dept, salary
from employee
having salary > (select max(salary) from employee where dept = 'sale')
```
{
"node_id": "mysql-6bb279fa10fa4633a3af51ff7001f5ce",
"keywords": [],
"keywords": ["subquery", "子查询", "any"],
"children": [],
"export": [],
"keywords_must": [],
......
......@@ -2,13 +2,13 @@
现有员工表
```postgresql
```mysql
create table employee
(
id serial primary key,
name text,
dept text,
salary money
id int primary key auto_increment,
name varchar(256),
dept varchar(256),
salary decimal(12, 4)
)
```
......@@ -16,7 +16,7 @@ create table employee
## 答案
```postgresql
```mysql
select id, name, dept, salary
from employee
where salary > (select max(salary)
......@@ -28,7 +28,7 @@ where salary > (select max(salary)
### A
```postgresql
```mysql
select id, name, dept, salary
from employee
where dept = 'sale'
......@@ -38,7 +38,7 @@ having salary > max(salary)
### B
```postgresql
```mysql
select l.id, l.name, l.dept, l.salary
from employee as l
join employee as r on l.salary > max(r.salary)
......@@ -48,7 +48,7 @@ group by r.dept
### C
```postgresql
```mysql
select id, name, dept, salary
from employee
having salary > (select max(salary) from employee where dept = 'sale')
......
# 获取连续区间
SmartMarket 交易所的系统中,所有订单在生成时,都从一个 PostgreSQL Sequence 中获取唯一的 序列号,完成交易计算后各个撮合程序将其插入如下的 orders 表中:
SmartMarket 交易所的系统中,所有订单在生成时,都从一个 oracle Sequence 中获取唯一的
序列号,完成交易计算后各个撮合程序将其插入如下的 orders 表中:
```postgresql
```mysql
create table orders
(
id integer primary key,
meta jsonb default '{}'::jsonb,
content jsonb default '{}'::jsonb
content json
-- ignore other definitions...
);
```
后续的结算系统需要连续的获取订单,以便处理一些顺序敏感的业务。但是撮合发生在很多个异步节点上,它们只能保证最终会将所有订单都保存到 orders 表,确保 id 列最终是连续的,但是最新插入的一段记录集有可能不连续。而我们希望结算系统成批
的读取数据,以优化性能,那么在结算系统有它最后处理的订单id的前提下,下面哪一个查询可以确保从这个id向前读取 id 连续 的一批订单?
后续的结算系统需要连续的获取订单,以便处理一些顺序敏感的业务。但是撮合发生在很多个异步节
点上,它们只能保证最终会将所有订单都保存到 orders 表,确保 id 列最终是连续的,但是最新
插入的一段记录集有可能不连续。而我们希望结算系统成批的读取数据,以优化性能,那么在结算系
统有它最后处理的订单id的前提下,下面哪一个查询可以确保从这个id向前读取 id 连续 的一批
订单?
## 答案
```postgresql
```mysql
with recursive r(id) as (select id
from orders
where id = $1
......@@ -25,7 +28,7 @@ with recursive r(id) as (select id
select d.id
from orders as d
join r on d.id = r.id + 1)
select orders.id, meta, content
select orders.id, content
from orders
join r on orders.id = r.id;
```
......@@ -38,8 +41,8 @@ from orders
### B
```postgresql
select data.id, meta, content
```mysql
select data.id, content
from orders
join orders as r on orders.id = r.id - 1
where id = $1;
......@@ -47,15 +50,15 @@ where id = $1;
### C
```postgresql
select id, meta, content
```mysql
select id, content
from orders
where id in (select id from orders where id = id + 1);
```
### D
```postgresql
```mysql
with r as (select id
from orders
where id = $1
......@@ -63,7 +66,7 @@ with r as (select id
select d.id
from orders as d
join r on d.id = r.id + 1)
select orders.id, meta, content
select orders.id, content
from orders
join r on orders.id = r.id;
```
\ No newline at end of file
......@@ -2,7 +2,7 @@
现有员工信息表如下:
```postgresql
```mysql
create table employee
(
id serial primary key,
......@@ -16,7 +16,7 @@ create table employee
## 答案
```postgresql
```mysql
select id, name, dept, salary
from (select id, name, dept, salary, rank() over (partition by dept order by salary desc) as r
from employee) as t
......@@ -27,7 +27,7 @@ where r <= 5;
### 结构错误
```postgresql
```mysql
select id, name, dept, max(salary) as salary
from employee
group by dept
......@@ -36,7 +36,7 @@ having id < 6;
### 结构错误
```postgresql
```mysql
select l.id, l.name, l.dept, l.salary
from employee as l
join (select max(salary) as salary, dept
......@@ -48,7 +48,7 @@ where count(r.id) <= 5;
### 结构错误
```postgresql
```mysql
select l.id, l.name, l.dept, l.salary
from employee as l
join (select max(salary, 5) as salary, dept
......@@ -59,7 +59,7 @@ from employee as l
### 结构错误
```postgresql
```mysql
select id, name, dept, salary, rank() over (partition by dept order by salary desc) as r
from employee
where r <= 5;
......@@ -67,7 +67,7 @@ where r <= 5;
### 结构错误
```postgresql
```mysql
select id, name, dept, salary, rank() as r over (partition by dept order by salary desc)
from employee
where r <= 5;
......
......@@ -2,12 +2,11 @@
现有销售记录表
```postgresql
```mysql
create table sales(
id serial primary key ,
sku_id integer not null ,
amount money,
meta jsonb default '{}'::jsonb,
amount decimal(12, 4),
created_at timestamp default now()
);
create index on sales(created_at);
......@@ -17,20 +16,20 @@ create index on sales(created_at);
## 答案
```postgresql
```mysql
select sku_id,
sum(case extract(month from created_at) when 1 then amount else 0::money end) as Jan,
sum(case extract(month from created_at) when 2 then amount else 0::money end) as Feb,
sum(case extract(month from created_at) when 3 then amount else 0::money end) as Mar,
sum(case extract(month from created_at) when 4 then amount else 0::money end) as Apr,
sum(case extract(month from created_at) when 5 then amount else 0::money end) as May,
sum(case extract(month from created_at) when 6 then amount else 0::money end) as June,
sum(case extract(month from created_at) when 7 then amount else 0::money end) as July,
sum(case extract(month from created_at) when 8 then amount else 0::money end) as Aug,
sum(case extract(month from created_at) when 9 then amount else 0::money end) as Sept,
sum(case extract(month from created_at) when 10 then amount else 0::money end) as Oct,
sum(case extract(month from created_at) when 11 then amount else 0::money end) as Nov,
sum(case extract(month from created_at) when 12 then amount else 0::money end) as Dec
sum(case extract(month from created_at) when 1 then amount else 0 end) as Jan,
sum(case extract(month from created_at) when 2 then amount else 0 end) as Feb,
sum(case extract(month from created_at) when 3 then amount else 0 end) as Mar,
sum(case extract(month from created_at) when 4 then amount else 0 end) as Apr,
sum(case extract(month from created_at) when 5 then amount else 0 end) as May,
sum(case extract(month from created_at) when 6 then amount else 0 end) as June,
sum(case extract(month from created_at) when 7 then amount else 0 end) as July,
sum(case extract(month from created_at) when 8 then amount else 0 end) as Aug,
sum(case extract(month from created_at) when 9 then amount else 0 end) as Sept,
sum(case extract(month from created_at) when 10 then amount else 0 end) as Oct,
sum(case extract(month from created_at) when 11 then amount else 0 end) as Nov,
sum(case extract(month from created_at) when 12 then amount else 0 end) as Dec
from sales
where created_at between '2020-01-01'::timestamp and '2021-01-01'::timestamp
group by sku_id;
......@@ -40,7 +39,7 @@ group by sku_id;
### 格式不相符
```postgresql
```mysql
select sku_id, extract(month from created_at) as month, sum(amount)
from sales
where created_at between '2020-01-01'::timestamp and '2021-01-01'::timestamp
......@@ -49,7 +48,7 @@ group by 1, 2;
### 计算逻辑错误
```postgresql
```mysql
select sku_id,
sum(amount) as Jan,
sum(amount) as Feb,
......@@ -70,7 +69,7 @@ group by sku_id, extract(month from created_at);
### 计算格式错误
```postgresql
```mysql
select sku_id,
sum(amount having extract(month from created_at) = 1) as Jan,
sum(amount having extract(month from created_at) = 2) as Feb,
......
......@@ -2,7 +2,7 @@
现有一个表
```postgresql
```mysql
create table book_in(
login integer primary key ,
score integer default 0
......@@ -14,15 +14,15 @@ create table book_in(
## 答案
```postgresql
insert into book_in(login, score) values ($1, $2) on conflict do update set score=$2;
```mysql
insert into book_in(login, score) values ($1, $2) on DUPLICATE KEY update score=$2;
```
## 选项
### A
```postgresql
```mysql
try
insert into book_in(login, score) values ($1, $2);
catch
......@@ -33,18 +33,18 @@ finally
### B
```postgresql
```mysql
insert into book_in(login, score) select $1, $2;
```
### C
```postgresql
```mysql
replace book_in(login, score) select $1, $2;
```
### D
```postgresql
```mysql
upsert into book_in(login, score) select $1, $2;
```
......@@ -2,27 +2,32 @@
现有 test1 表如下
```postgresql
```mysql
create table test1(a integer primary key );
```
我们执行下面的语句
```postgresql
```mysql
CREATE PROCEDURE transaction_test1()
LANGUAGE plpgsql
AS $$
BEGIN
FOR i IN 0..9 LOOP
INSERT INTO test1 (a) VALUES (i);
IF i % 2 = 0 THEN
declare idx int;
set idx = 0;
iter: LOOP
start transaction ;
INSERT INTO test1 (a) VALUES (idx);
IF (idx % 2) = 0 THEN
COMMIT;
ELSE
ROLLBACK;
END IF;
END LOOP;
IF idx < 10 THEN
set idx = idx + 1;
ITERATE iter;
END IF;
LEAVE iter;
END LOOP iter;
END;
$$;
CALL transaction_test1();
```
......@@ -31,13 +36,13 @@ CALL transaction_test1();
## 答案
每当循环迭代到偶数的时候提交插入,最终 test1 表中是`0,2,4,6,8`
每当循环迭代到偶数的时候提交插入,最终 test1 表中是`0,2,4,6,8,10`
## 选项
### A
以最后一次提交为准,最终 test1 表中是 0 到 9 共九个数字。
以最后一次提交为准,最终 test1 表中是 0 到 10 共11个数字。
### B
......
......@@ -8,8 +8,7 @@
],
"children": [],
"export": [
"daily_payment.json",
"daily_payment_2.json"
"daily_payment.json"
],
"keywords_must": [
"索引",
......
......@@ -2,27 +2,28 @@
数据分析组需要经常执行以下查询生成从昨天到之前某一天的交易量统计
```postgresql
select payment_date::date as day, sum(amount)
```mysql
select date(payment_date) as day, sum(amount)
from payment
where (payment_date::date) between $1 and 'yesterday'::date
group by payment_date::date;
where date(payment_date) between $1 and DATE_SUB(CURDATE(), INTERVAL 1 DAY)
group by date(payment_date);
```
现在这个查询很慢,payment 表的信息如下:
```text
Table "public.payment"
Column | Type | Collation | Nullable | Default
--------------+-----------------------------+-----------+----------+---------------------------------------------
payment_id | integer | | not null | nextval('payment_payment_id_seq'::regclass)
customer_id | smallint | | not null |
staff_id | smallint | | not null |
rental_id | integer | | not null |
amount | numeric(5,2) | | not null |
payment_date | timestamp without time zone | | not null |
Indexes:
"payment_pkey" PRIMARY KEY, btree (payment_id)
mysql> desc payment;
+---------------+---------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------+---------------+------+-----+---------+----------------+
| payment_id | int | NO | PRI | NULL | auto_increment |
| customer_id | int | YES | | NULL | |
| staff_id | int | YES | | NULL | |
| rental_id | int | YES | | NULL | |
| amount | decimal(12,8) | YES | | NULL | |
| pathment_date | timestamp | YES | | NULL | |
+---------------+---------------+------+-----+---------+----------------+
6 rows in set (0.12 sec)
```
应该如何优化这个查询?
......@@ -31,8 +32,8 @@ Indexes:
建立表达式索引
```postgresql
create index on payment((payment_date::date));
```mysql
alter table payment add index idx_payment_date((date(payment_date)));
```
## 选项
......@@ -41,16 +42,16 @@ create index on payment((payment_date::date));
建立视图
```postgresql
create view view_daily_payment as select payment_date::date as day, amount from payment;
```mysql
create view view_daily_payment as select date(payment_date) as day, amount from payment;
```
然后在视图 view_daily_payment 上执行
```postgresql
```mysql
select day, sum(amount)
from view_daily_payment
where day between $1 and 'yesterday'::date
where day between $1 and DATE_SUB(CURDATE(), INTERVAL 1 DAY)
group by day
```
......@@ -58,23 +59,23 @@ group by day
在 payment_date 列上建立索引
```postgresql
create index on payment(payment_date);
```mysql
create index idx_payment_date on payment(payment_date);
```
### 可以简化语句,但对优化没有帮助
建立计算列
```postgresql
alter table payment add day date generated always as ( payment_date::date ) stored
```mysql
alter table payment add day date generated always as (date(payment_date)) stored;
```
然后使用它改写查询
```postgresql
```mysql
select day as day, sum(amount)
from payment
where day between $1 and 'yesterday'::date
where day between $1 and date('yesterday')
group by day;
```
\ No newline at end of file
# 每日报表优化
# 每日报表
统计过去一段时间的数据,你发现 payment 表上每天的订单量很大,下面这个查询的统计过程占用了大多数数据库资源,查询不会
早止当天,总是在历史上某一个日期段内查询
```postgresql
select payment_date::date as day, sum(amount)
from payment
where (payment_date::date) between $1 and $2
group by payment_date::date;
```
payment 表的信息如下:
```text
Table "public.payment"
Column | Type | Collation | Nullable | Default
--------------+-----------------------------+-----------+----------+---------------------------------------------
payment_id | integer | | not null | nextval('payment_payment_id_seq'::regclass)
customer_id | smallint | | not null |
staff_id | smallint | | not null |
rental_id | integer | | not null |
amount | numeric(5,2) | | not null |
payment_date | timestamp without time zone | | not null |
Indexes:
"payment_pkey" PRIMARY KEY, btree (payment_id)
```
怎样做是最有效的?
## 答案
建立物化视图并建立索引。
```postgresql
create materialized view view_daily_payment as
select payment_date::date as day, sum(amount) as amount from payment group by day;
create index on view_daily_payment(day);
```
使用
```postgresql
select day, amount from view_daily_payment where day between $1 and $2;
```
进行查询。并且每天定时执行一次刷新命令
```postgresql
REFRESH MATERIALIZED VIEW view_daily_payment;
```
## 选项
### 不会优化 sum 和 group by
在 payment_date 列上建立索引
```postgresql
create index on payment(payment_date);
```
### 不会优化 sum
建立计算列
```postgresql
alter table payment add day date generated always as ( payment_date::date ) stored
```
然后使用它改写查询
```postgresql
select day as day, sum(amount)
from payment
where day between $1 and 'yesterday'::date
group by day;
```
### 优化了日期查询,但是不会优化统计过程
建立表达式索引
```postgresql
create index on payment((payment_date::date));
```
### 不做物化,对查询速度不会有显著改善
建立视图
```postgresql
create view view_daily_payment as select payment_date::date as day, amount from payment;
```
然后在视图 view_daily_payment 上执行
```postgresql
select day, sum(amount)
from view_daily_payment
where day between $1 and 'yesterday'::date
group by day
```
\ No newline at end of file
......@@ -547,7 +547,11 @@
{
"CASE": {
"node_id": "mysql-8e6cd4d5f4b446a2bc3f5402de9bd49c",
"keywords": [],
"keywords": [
"case",
"pivot",
"透视表"
],
"children": [],
"keywords_must": [],
"keywords_forbid": []
......@@ -803,7 +807,16 @@
],
"children": [
{
"ANY": {
"相关子查询": {
"node_id": "mysql-f045eeff32bd449c83afc76abdd65344",
"keywords": [],
"children": [],
"keywords_must": [],
"keywords_forbid": []
}
},
{
" ANY": {
"node_id": "mysql-6bb279fa10fa4633a3af51ff7001f5ce",
"keywords": [],
"children": [],
......
......@@ -3,7 +3,7 @@ create table orders (
item_id int,
amount int,
unit_price decimal(12, 4),
total_price decimal(12, 4),
total decimal(12, 4),
description varchar(2000),
ts timestamp default now(),
deal bool default false
......
create table payment(
payment_id int primary key auto_increment,
customer_id int,
staff_id int,
rental_id int,
amount decimal(12, 8),
payment_date timestamp
)
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册