Move the docs folder

This commit is contained in:
LINxiansheng
2022-02-10 14:51:49 +08:00
committed by LINxiansheng
parent 7c6dcc6712
commit d42f317422
1160 changed files with 0 additions and 3 deletions

View File

@ -0,0 +1,103 @@
通过 MySQL 客户端连接 OceanBase 租户
================================================
需要使用 OceanBase 的 MySQL 租户时,可以使用 MySQL 客户端连接该租户。
### 操作步骤如下:
1. 打开一
个命令行终端,确保环境变量 PATH 包含了 MySQL 客户端命令所在目录。
2. 参照下面格式提供 MySQL 的运行参数:
```javascript
$mysql -h192.168.1.101 -uroot@obmysql#obdemo -P2883 -pabcABC123 -c -A oceanbase
```
**说明**
* -h:提供 OceanBase 数据库连接 IP,通常是一个 OBProxy 地址。
* -u:提供租户的连接账户,格式有两种:用户名@租户名#集群名 或者 集群名:租户名:用户名 。MySQL 租户的管理员用户名默认是 root 。
* -P:提供 OceanBase 数据库连接端口,也是 OBProxy 的监听端口,默认是2883,可以自定义。
* -p:提供账户密码,为了安全可以不提供,改为在后面提示符下输入,密码文本不可见。
* -c:表示在 MySQL 运行环境中不要忽略注释。
* -A:表示在 MySQL 连接数据库时不自动获取统计信息。
* oceanbase:访问的数据库名,可以改为业务数据库。
3. 连接成功后,默认会有命令行提示符:
```javascript
MySQL [oceanbase]>
```
4. 如果要退出 OceanBase 命令行,输入 exit 后回车,或者按快捷键 ctrl + d。
### 如下示例为通过 MySQL 客户端连接 OceanBase 的 MySQL 租户。
```javascript
$mysql -h192.168.1.101 -uroot@obmysql#obdemo -P2883 -pabcABC123 -c -A oceanbase
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MySQL connection id is 62488
Server version: 5.6.25 OceanBase 2.2.20 (...) (Built Aug 10 2019 15:27:33)
<...省略...>
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MySQL [oceanbase]> show databases;
+--------------------+
| Database |
+--------------------+
| oceanbase |
| information_schema |
| mysql |
| test |
+--------------------+
4 rows in set (0.00 sec)
MySQL [oceanbase]> exit
Bye
```

View File

@ -0,0 +1,106 @@
通过 obclient 连接 OceanBase 租户
================================================
obclient 是 OceanBase 专用的命令行客户端工具,通过 obclient 您可以连接 OceanBase 的 MySQL 和 ORACLE 租户。
### 操作步骤如下:
1. 打开一个命令行终端。
2. 参照下面格式提供 obclient 的运行参数:
```javascript
$ obclient -h192.168.1.101 -uroot@obmysql#obdemo -P2883 -pabcABC123 -c -A oceanbase
```
**说明**
* -h:提供 OceanBase数据库连接的IP,通常是一个 OBProxy 地址。
* -u:提供租户的连接帐户,格式有两种:"用户名@租户名#集群名"或者"集群名:租户名:用户名"。Oracle 租户的管理员用户名默认是sys。
* -P:提供 OceanBase 数据库连接端口,也是 OBProxy 的监听端口,默认是 2883,可以自定义。
* -p:提供帐户密码。为了安全可以不提供,改为在后面提示符下输入,密码文本不可见。
* -c:表示在将 SQL 语句中的注释发往数据库端。
* -A:表示在连接数据库时不去获取全部表信息,可以使登录数据库速度最快。
* oceanbase:访问的数据库名,可以改为业务数据库
3. 连接成功后,默认会有如下命令行提示符。
```javascript
obclient>
```
4. 如果要退出 OceanBase 命令行,输入 exit 后回车,或者按快捷键 ctrl + d。
以下示例为通过 obclient 连接 OceanBase 的 MySQL 租户。
```javascript
$obclient -h192.168.1.101 -uroot@obmysql#obdemo -P2883 -pabcABC123 -c -A oceanbase
obclient: [Warning] Using a password on the command line interface can be insecure.
Welcome to the OceanBase monitor. Commands end with ; or \g.
Your OceanBase connection id is 64621
Server version: 5.6.25 OceanBase 2.2.20 (...) (Built Aug 10 2019 15:27:33)
<省略>
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
obclient> select sysdate();
+---------------------+
| sysdate() |
+---------------------+
| 2020-04-01 21:53:22 |
+---------------------+
1 row in set (0.00 sec)
obclient> exit
Bye
```

View File

@ -0,0 +1,42 @@
通过 ODC 连接 OceanBase 数据库
============================================
操作步骤
-------------
1. 登录ODC。ODC第一次运行时,加载时间会比较长,请耐心等待。
![image.png](https://help-static-aliyun-doc.aliyuncs.com/assets/img/zh-CN/0475055061/p148887.png "image.png")
2. ODC启动完成后,会提示创建连接。
![image.png](https://help-static-aliyun-doc.aliyuncs.com/assets/img/zh-CN/0475055061/p148888.png "image.png")
3. 点击 **新建连接** ,在创建连接页面选择 **连接模式** 为 MySQL,在页面中输入 **连接名称****主机名****端口****集群****租户****数据库用户名****数据库密码** ,点击 **保存** ,如果可以保存成功,说明连接数据库成功。​![](https://cdn.nlark.com/yuque/0/2020/png/177325/1600747410838-342d8f75-a197-4caf-bc10-caa331cc427b.png)​​​​
<!-- -->
4. 连接创建成功后,会显示如下界面,双击该连接面板就可以打开连接。​![](https://cdn.nlark.com/yuque/0/2020/png/177325/1600747687738-dd322407-8f67-43bf-8e1a-ee6e839ab4fe.png)​

View File

@ -0,0 +1,149 @@
创建 OceanBase 示例数据库 TPCC
============================================
默认情况 OceanBase 没有创建示例数据库 TPCC,需要手动创建。示例数据库必须在业务租户下创建。有关示例数据库介绍请参考 [关于示例数据库 TPCC](../../7.developer-guide-1/1.preface-2/4.about-the-sample-database-tpcc-2.md)。
租户创建好后,需要创建相应的 DataBase 来存放示例数据库的对象,还要分配相应的用户和访问权限。
示例
-----------
1. 通过 obclient 连接 MySQL 租户。
```javascript
#obclient -h192.168.1.101 -uroot@obmysql#obdemo -P2883 -pabcABC123 -A oceanbase
obclient: [Warning] Using a password on the command line interface can be insecure.
Welcome to the OceanBase monitor. Commands end with ; or \g.
Your OceanBase connection id is 57981
Server version: 5.6.25 OceanBase 2.2.20 (...) (Built Aug 10 2019 15:27:33)
<...省略...>
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
```
2. 创建一个数据库。
```javascript
obclient> create database tpccdb;
Query OK, 1 row affected (0.02 sec)
obclient> show databases;
+--------------------+
| Database |
+--------------------+
| oceanbase |
| information_schema |
| mysql |
| test |
| tpccdb |
+--------------------+
5 rows in set (0.01 sec)
```
3. 创建一个用户并赋权。
```javascript
obclient> grant all privileges on tpccdb.* to tpcc identified by '123456';
Query OK, 0 rows affected (0.02 sec)
obclient> show grants for tpcc;
+----------------------------------------------+
| Grants for tpcc@% |
+----------------------------------------------+
| GRANT USAGE ON *.* TO 'tpcc' |
| GRANT SELECT ON `oceanbase`.* TO 'tpcc' |
| GRANT ALL PRIVILEGES ON `tpccdb`.* TO 'tpcc' |
+----------------------------------------------+
3 rows in set (0.01 sec)
obclient>
```
4. 创建数据库对象
```javascript
obclient> use tpccdb;
Database changed
obclient> source create_mysql_tables.sql
Query OK, 0 rows affected (0.01 sec)
<...省略...>
Query OK, 0 rows affected (0.01 sec)
+------------------+
| Tables_in_tpccdb |
+------------------+
| cust |
| dist |
| hist |
| item |
| load_hist |
| load_proc |
| nord |
| ordl |
| ordr |
| stock_item |
| stok |
| ware |
+------------------+
12 rows in set (0.00 sec)
```
5. 初始化表数据。
```javascript
obclient> source init_data.sql
Query OK, 0 rows affected (0.01 sec)
<...省略...>
Query OK, 0 rows affected (0.01 sec)
+------------+----------+
| table_name | rows_cnt |
+------------+----------+
| WARE | 2 |
| DIST | 20 |
| NORD | 40 |
| ORDR | 60 |
| HIST | 240 |
| ITEM | 622 |
| ORDL | 626 |
| CUST | 1040 |
| STOK | 1244 |
+------------+----------+
9 rows in set (0.01 sec)
```

View File

@ -0,0 +1,133 @@
通过 obclient 探索 OceanBase MySQL 租户
======================================================
在 obclient 命令行环境里,可以通过一些命令或者 SQL 查看数据库对象或者表属性和数据。
示例
-----------
* 通过 obclient 查看 MySQL 租户的数据库对象。
```javascript
#obclient -h192.168.1.101 -utpcc@obmysql#obdemo -P2883 -p123456 -A tpccdb
obclient> show tables;
+------------------+
| Tables_in_tpccdb |
+------------------+
| cust |
| dist |
| hist |
| item |
| load_hist |
| load_proc |
| nord |
| ordl |
| ordr |
| stock_item |
| stok |
| ware |
+------------------+
12 rows in set (0.01 sec)
```
* 通过 obclient 查看 MySQL 租户的表属性
```javascript
obclient> desc ordl;
+----------------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------------+--------------+------+-----+---------+-------+
| ol_w_id | int(11) | NO | PRI | NULL | |
| ol_d_id | int(11) | NO | PRI | NULL | |
| ol_o_id | int(11) | NO | PRI | NULL | |
| ol_number | int(11) | NO | PRI | NULL | |
| ol_delivery_d | date | YES | | NULL | |
| ol_amount | decimal(6,2) | YES | | NULL | |
| ol_i_id | int(11) | YES | | NULL | |
| ol_supply_w_id | int(11) | YES | | NULL | |
| ol_quantity | int(11) | YES | | NULL | |
| ol_dist_info | char(24) | YES | | NULL | |
+----------------+--------------+------+-----+---------+-------+
10 rows in set (0.01 sec)
obclient> show create table ordl\G
*************************** 1. row ***************************
Table: ordl
Create Table: CREATE TABLE `ordl` (
`ol_w_id` int(11) NOT NULL,
`ol_d_id` int(11) NOT NULL,
`ol_o_id` int(11) NOT NULL,
`ol_number` int(11) NOT NULL,
`ol_delivery_d` date DEFAULT NULL,
`ol_amount` decimal(6,2) DEFAULT NULL,
`ol_i_id` int(11) DEFAULT NULL,
`ol_supply_w_id` int(11) DEFAULT NULL,
`ol_quantity` int(11) DEFAULT NULL,
`ol_dist_info` char(24) DEFAULT NULL,
PRIMARY KEY (`ol_w_id`, `ol_d_id`, `ol_o_id`, `ol_number`)
) DEFAULT CHARSET = utf8mb4 ROW_FORMAT = DYNAMIC COMPRESSION = 'zstd_1.0' REPLICA_NUM = 1 BLOCK_SIZE = 16384 USE_BLOOM_FILTER = FALSE TABLET_SIZE = 134217728 PCTFREE = 10 TABLEGROUP = 'tpcc_group'
partition by hash(ol_w_id) partitions 6
1 row in set (0.02 sec)
```
* 通过 obclient 查看 MySQL 租户的表数据
```javascript
obclient> select * from ware;
+------+---------+--------+------------+---------------------+----------------------+--------------+---------+-----------+
| w_id | w_ytd | w_tax | w_name | w_street_1 | w_street_2 | w_city | w_state | w_zip |
+------+---------+--------+------------+---------------------+----------------------+--------------+---------+-----------+
| 1 | 1200.00 | 0.1868 | n1P4zYo8OH | jTNkXKWXOdh | lf9QXTXXGoF04IZBkCP7 | srRq15uvxe5 | GQ | 506811111 |
| 2 | 1200.00 | 0.0862 | L6xwRsbDk | xEdT1jkENtbLwoI1Zb0 | NT0j4RCQ4OqrS | vlwzndw2FPrO | XR | 063311111 |
+------+---------+--------+------------+---------------------+----------------------+--------------+---------+-----------+
2 rows in set (0.01 sec)
```
也可以使用参数'\\G'结尾按列展示每行数据
```javascript
obclient> select * from ware\G
*************************** 1. row ***************************
w_id: 1
w_ytd: 1200.00
w_tax: 0.1868
w_name: n1P4zYo8OH
w_street_1: jTNkXKWXOdh
w_street_2: lf9QXTXXGoF04IZBkCP7
w_city: srRq15uvxe5
w_state: GQ
w_zip: 506811111
*************************** 2. row ***************************
w_id: 2
w_ytd: 1200.00
w_tax: 0.0862
w_name: L6xwRsbDk
w_street_1: xEdT1jkENtbLwoI1Zb0
w_street_2: NT0j4RCQ4OqrS
w_city: vlwzndw2FPrO
w_state: XR
w_zip: 063311111
2 rows in set (0.01 sec)
obclient>
```

View File

@ -0,0 +1,40 @@
关于查询语句
===========================
一个查询,指一个SELECT SQL 语句,从一个或多个表或者视图里查询数据。
最简单的SQL语句格式是:
```javascript
SELECT select_list FROM table_list
```
* *select_list 指定的可以是后面 table_list 里的列,也可以是函数值、字符常量、计算变量等。*
* *table_list 指定的是包含所查数据的表或者视图。*
上面是简单的查询语句格式,实际 table_list 还可以是一个子查询语句,同时还可以带上 where 条件以限定返回的结果要符合某种条件。
需要注意的是,在 MySQL 租户里,FROM table_list 可以没有,这样 select_list 就不是具体的列,而是常量或者变量值。如下面这个SQL:
```javascript
$obclient -h192.168.1.101 -utpcc@obmysql#obdemo -P2883 -p123456 -A tpccdb
obclient> select '中', 6*6 ;
+-----+-----+
| | 6*6 |
+-----+-----+
| | 36 |
+-----+-----+
1 row in set (0.00 sec)
```
关于查询语句的详细用法请参考《OceanBase SQL参考(MySQL模式)》。

View File

@ -0,0 +1,34 @@
在 ODC 中运行查询
================================
本节展示如何在 ODC 中通过 SQL 编辑器执行查询语句。
前提条件
-------------------------
已在 ODC 中创建了到 OceanBase 数据库的连接。
操作步骤
-------------------------
1. 进入 ODC,找到创建好的数据库连接,单击进入对应的数据库管理页面。
2. 单击上方导航栏中的 **工作台** ,在弹出的下拉菜单中选择 **SQL 窗口**
3. 在打开的 **SQL 窗口** 中输入查询语句,如果有多条查询语句,每个语句都以";"结尾。单击 **运行****运行当前语句** 按钮。
4. 下面 **结果** 栏会顺序显示查询结果,如果有多条查询语句,每条查询语句对应一个结果栏。![](https://cdn.nlark.com/yuque/0/2020/png/177325/1600310020517-1f4570ae-b378-4c75-b9f7-fb3deefdaf5e.png?x-oss-process=image%2Fresize%2Cw_1500)​

View File

@ -0,0 +1,38 @@
查询表里符合特定搜索条件的数据
====================================
当要查询满足特定搜索条件的数据时,给 SELECT 查询语句增加一个 WHERE 子句即可。SQL 语句格式如下:
```javascript
SELECT select_list FROM table_list
WHERE query_condition
```
以"在 ODC 中运行查询"页面的图为例,查询 2 号仓库第 5 区的订单,SQL 语句如下:
```javascript
SELECT * FROM ordr WHERE o_w_id=2 and o_d_id=5 ;
```
在 ODC 中的查询结果如下图所示:![](https://cdn.nlark.com/yuque/0/2020/png/177325/1600744555056-0404ef68-710f-4829-a877-a82853b7fabd.png)​
执行结果如下:
```unknow
+--------+--------+------+--------+--------------+----------+-------------+------------+
| o_w_id | o_d_id | o_id | o_c_id | o_carrier_id | o_ol_cnt | o_all_local | o_entry_d |
+--------+--------+------+--------+--------------+----------+-------------+------------+
| 2 | 5 | 2100 | 2100 | 5 | 12 | 1 | 2020-02-15 |
| 2 | 5 | 2101 | 4 | NULL | 11 | 1 | 2020-02-15 |
| 2 | 5 | 2102 | 440 | NULL | 7 | 1 | 2020-02-15 |
+--------+--------+------+--------+--------------+----------+-------------+------------+
3 rows in set (0.01 sec)
```

View File

@ -0,0 +1,91 @@
对查询的结果进行排序
===============================
查询结果返回的顺序可能是任意顺序,如果想要根据特定字段排序返回结果集,需要在 SELECT 语句最后面增加 ORDER BY 子句指定返回顺序。SQL 语句格式如下:
```javascript
SELECT select_list FROM table_list
WHERE query_condition
ORDER BY column_list
```
如查看 2 号仓库第 5 区的客户,按姓名排序,SQL 语句如下:
```javascript
SELECT c_id, c_last,c_first,c_middle, c_w_id, c_d_id, c_credit, c_since
FROM cust
WHERE c_w_id=2 AND c_d_id=5
ORDER BY c_last, c_first;
```
在 ODC 中查询结果如下:​![](https://cdn.nlark.com/yuque/0/2020/png/177325/1600744650740-50818ad6-2879-482f-a711-7a65a2380444.png)​
执行结果如下:
```unknow
+------+----------------+------------------+----------+--------+--------+----------+------------+
| c_id | c_last | c_first | c_middle | c_w_id | c_d_id | c_credit | c_since |
+------+----------------+------------------+----------+--------+--------+----------+------------+
| 202 | ABLEBAROUGHT | omHvv5eG | OE | 2 | 5 | GC | 2020-02-15 |
| 272 | ABLECALLYOUGHT | x0ikkFsuG | OE | 2 | 5 | GC | 2020-02-15 |
| 2106 | ABLECALLYPRI | Hksk96bvVRAZ | OE | 2 | 5 | GC | 2020-02-15 |
| 2813 | ABLEPRESEING | GxtYNqeRZFIaWmN | OE | 2 | 5 | GC | 2020-02-15 |
| 2360 | ANTIATIONATION | BcIWNvikBc | OE | 2 | 5 | GC | 2020-02-15 |
| 2500 | ANTIEINGCALLY | WXBmhcRTWe | OE | 2 | 5 | GC | 2020-02-15 |
| 658 | ANTIESECALLY | ONPLFp6Htl | OE | 2 | 5 | BC | 2020-02-15 |
| 1085 | ANTIOUGHTABLE | SstdwQNJJ | OE | 2 | 5 | GC | 2020-02-15 |
| 2247 | ANTIPRIOUGHT | R1VEFjdPlOioo | OE | 2 | 5 | GC | 2020-02-15 |
| 2100 | ATIONABLEESE | PzFg81YvfBC | OE | 2 | 5 | BC | 2020-02-15 |
| 2196 | ATIONATIONBAR | ReFiFtMxfo1qG5 | OE | 2 | 5 | GC | 2020-02-15 |
| 871 | ATIONCALLYBAR | W7ZNcPqp5sBWNi | OE | 2 | 5 | GC | 2020-02-15 |
| 2999 | ATIONCALLYPRI | eQbIWEimKcM80xNB | OE | 2 | 5 | GC | 2020-02-15 |
| 849 | ATIONPRESATION | Z6V2PdM8B0b9hQ8d | OE | 2 | 5 | GC | 2020-02-15 |
| 8 | BARBARCALLY | jXrw6CCdzcamEi | OE | 2 | 5 | GC | 2020-02-15 |
| 4 | BARBARPRI | KKvDumYX9AwHuxX | OE | 2 | 5 | GC | 2020-02-15 |
| 1983 | BAROUGHTANTI | XeYW3WKpfBITC1aB | OE | 2 | 5 | GC | 2020-02-15 |
| 1590 | BAROUGHTCALLY | Y886PI3rFsHCSMbF | OE | 2 | 5 | GC | 2020-02-15 |
| 1529 | BAROUGHTPRI | pyP6QQj7FB | OE | 2 | 5 | GC | 2020-02-15 |
| 34 | BARPRIPRI | gXmuxvj2R | OE | 2 | 5 | GC | 2020-02-15 |
| 1785 | CALLYABLEESE | LsWK1Zs1pm | OE | 2 | 5 | GC | 2020-02-15 |
| 2765 | CALLYABLEOUGHT | b0maEo4Nm2JgW2j | OE | 2 | 5 | GC | 2020-02-15 |
| 2102 | CALLYABLEOUGHT | wPS9EgAgztLRvSuZ | OE | 2 | 5 | GC | 2020-02-15 |
| 798 | CALLYEINGCALLY | Z9T8FivHqeaO | OE | 2 | 5 | GC | 2020-02-15 |
| 2793 | CALLYEINGOUGHT | eVQqIPDaGOb7N3EN | OE | 2 | 5 | GC | 2020-02-15 |
| 1370 | CALLYESEEING | J8Cakezt | OE | 2 | 5 | GC | 2020-02-15 |
| 2660 | CALLYPRESPRES | FgxeQplwu | OE | 2 | 5 | GC | 2020-02-15 |
| 2401 | CALLYPRIANTI | fJjIGGGH7Fdn1Kp | OE | 2 | 5 | BC | 2020-02-15 |
| 926 | EINGABLEESE | NZLtbu8Jb7Qi | OE | 2 | 5 | GC | 2020-02-15 |
| 2970 | EINGABLEOUGHT | PLnJDvKTwR0ireM | OE | 2 | 5 | GC | 2020-02-15 |
| 2137 | EINGANTIEING | bDPeSSyD7 | OE | 2 | 5 | GC | 2020-02-15 |
| 1334 | EINGBAREING | ep86qqrvFlD | OE | 2 | 5 | GC | 2020-02-15 |
| 993 | EINGEINGABLE | mxu2u3eo | OE | 2 | 5 | GC | 2020-02-15 |
| 956 | EINGESEESE | q02t2c9oR7 | OE | 2 | 5 | GC | 2020-02-15 |
| 916 | EINGOUGHTESE | ungAvrh8dWoGlQlP | OE | 2 | 5 | GC | 2020-02-15 |
| 569 | ESEANTIATION | xIZPuIwBJXxVIER | OE | 2 | 5 | GC | 2020-02-15 |
| 1433 | ESEBARESE | jpTpJk5diH | OE | 2 | 5 | GC | 2020-02-15 |
| 2405 | ESEBARESE | ZXKb7eR96iGg | OE | 2 | 5 | GC | 2020-02-15 |
| 2101 | ESEPRESATION | DQUk9dys | OE | 2 | 5 | GC | 2020-02-15 |
| 2348 | OUGHTCALLYANTI | w0rDw8txdIPfeElQ | OE | 2 | 5 | GC | 2020-02-15 |
| 1093 | OUGHTCALLYESE | GBx3akVCEuTPLa | OE | 2 | 5 | BC | 2020-02-15 |
| 193 | OUGHTEINGABLE | ImIEJkCzrYtEpaV4 | OE | 2 | 5 | GC | 2020-02-15 |
| 1318 | PRESATIONEING | uT4TGkIdWf | OE | 2 | 5 | GC | 2020-02-15 |
| 1813 | PRESATIONESE | SsF8v3NE | OE | 2 | 5 | GC | 2020-02-15 |
| 1991 | PRESESEANTI | GhytcH1EQhY | OE | 2 | 5 | GC | 2020-02-15 |
| 414 | PRESOUGHTPRI | vTsmW2XU | OE | 2 | 5 | GC | 2020-02-15 |
| 1979 | PRESPRESANTI | GGsWcgaTLXjtXAN | OE | 2 | 5 | GC | 2020-02-15 |
| 1184 | PRESPRESEING | hs5Bd47ZlZghuD8 | OE | 2 | 5 | GC | 2020-02-15 |
| 440 | PRESPRIEING | O4Vjdc3hmk4DT | OE | 2 | 5 | GC | 2020-02-15 |
| 1766 | PRIABLEEING | hqPJlwGx6Qt0FXy | OE | 2 | 5 | GC | 2020-02-15 |
| 372 | PRICALLYOUGHT | HpbvP0rDZM3 | OE | 2 | 5 | GC | 2020-02-15 |
| 356 | PRIESEESE | lZlbGnZhIlYH6nP | OE | 2 | 5 | GC | 2020-02-15 |
+------+----------------+------------------+----------+--------+--------+----------+------------+
52 rows in set (0.01 sec)
```

View File

@ -0,0 +1,92 @@
从多个表里查询数据
==============================
如果要查询的数据需要从多个表中取时,需要在 SELECT 语句中 FROM 关键字后用 JOIN... ON 将多个表关联起来查询。通常这多个表在业务上是有联系的,如某些字段值的定义和数据相同,这个联系条件就是连接条件,会体现在 ON 后面的括号里,ON 里也可以包括过滤条件。SQL 语法格式如下:
```javascript
SELECT select_list FROM table_name1 [INNER] JOIN table_name2 ON ( join_condition )
WHERE query_condition
ORDER BY column_list
```
返回满足连接条件的多个表数据
-----------------------
默认 JOIN 返回的结果会满足 ON 后面的连接条件,这个又叫内连接(INNER JOIN),通常关键字 INNER 省略了就表示内连接。JOIN 前后的表分别称之为左表和右表,ON 里的条件描述的是左表和右表的连接条件和过滤条件。如果没有ON 子句,那 INNER JOIN 返回的就是左表和右表的全部数据,这个也称为笛卡儿积。
SQL 返回的结果会在 JOIN 结果上再经过 WHERE 后的查询条件过滤以及根据 ORDER BY 后的列排序。
**示例:** **使用** **JOIN从多个表里查询数据**
```javascript
obclient> create table t1(id number not null primary key, name varchar(50));
Query OK, 0 rows affected (0.08 sec)
obclient> create table t2(id number not null primary key, name varchar(50));
Query OK, 0 rows affected (0.06 sec)
obclient> insert into t1 values(1,'A1'),(2,'B1'),(4,'D1'),(6,'F1'),(8,'H1'),(10,'J1');
Query OK, 6 rows affected (0.01 sec)
Records: 6 Duplicates: 0 Warnings: 0
obclient> insert into t2 values(1,'B2'),(3,'C2'),(6,'F2'),(9,'I2');
Query OK, 4 rows affected (0.01 sec)
Records: 4 Duplicates: 0 Warnings: 0
obclient> select t1.id, t1.name, t2.id, t2.name from t1 join t2 on (t1.id=t2.id) ;
+----+------+----+------+
| ID | NAME | ID | NAME |
+----+------+----+------+
| 1 | A1 | 1 | B2 |
| 6 | F1 | 6 | F2 |
+----+------+----+------+
2 rows in set (0.01 sec)
```
返回包含不满足连续条件的多个表数据
--------------------------
当需要 JOIN 返回的数据除了符合连接条件和过滤条件的数据外,还包括左表里满足左表的过滤条件但不满足连接条件的数据时,就可以使用左外连接(LEFT OUTER JOIN),也可以简写为左连接(LEFT JOIN)。左连接返回的结果里属于右表的数据如果不存在,则该列返回 NULL。
反之,如果 JOIN 返回的数据除了符合连接条件和过滤条件的数据外,还包括右表里满足右表的过滤条件但不满足连接条件的数据时,就可以使用右外连接(RIGHT OUTER JOIN),或简写为右连接(RIGHT JOIN)。右连接返回的结果里属于左表的数据如果不存在,则该列返回 NULL。
**示例:LEFT JOIN和RIGHT JOIN示例**
```javascript
obclient> select t1.id, t1.name, t2.id, t2.name from t1 left join t2 on (t1.id=t2.id) ;
+----+------+----+------+
| ID | NAME | ID | NAME |
+----+------+----+------+
| 1 | A1 | 1 | B2 |
| 2 | B1 | NULL | NULL |
| 4 | D1 | NULL | NULL |
| 6 | F1 | 6 | F2 |
| 8 | H1 | NULL | NULL |
| 10 | J1 | NULL | NULL |
+----+------+----+------+
6 rows in set (0.01 sec)
obclient> select t1.id, t1.name, t2.id, t2.name from t1 right join t2 on (t1.id=t2.id) ;
+----+------+----+------+
| ID | NAME | ID | NAME |
+----+------+----+------+
| 1 | A1 | 1 | B2 |
| NULL | NULL | 3 | C2 |
| 6 | F1 | 6 | F2 |
| NULL | NULL | 9 | I2 |
+----+------+----+------+
4 rows in set (0.00 sec)
```

View File

@ -0,0 +1,40 @@
查询中使用算术操作符
===============================
算术操作符包括:+(加)、-(减)、\*(乘)、/(除)、-(取反)、MOD(取模)。这些操作符可以作用在数值列上。
如"从多个表里查询数据" 页面的示例查询出客户购买的每个商品的数量和价格,其中数量乘以价格就是每类商品的支付总额。所以 select_list可以增加一列 t3.ol_quantity \* t4.i_price item_sum_price 。
```javascript
SELECT t1.c_first, t1.c_last, t1.c_credit, t2.o_ol_cnt, t2.o_entry_d, t3.ol_number, t3.ol_quantity, t4.i_name, t4.i_price, t3.ol_quantity * t4.i_price item_sum_price
FROM cust t1
JOIN ordr t2 ON (t1.c_id=t2.o_id AND t1.c_w_id=t2.o_w_id AND t1.c_d_id=t2.o_d_id)
JOIN ordl t3 ON (t2.o_id=t3.ol_o_id AND t2.o_w_id=t3.ol_w_id AND t2.o_d_id=t3.ol_d_id)
JOIN item t4 ON (t4.i_id=t3.ol_i_id )
WHERE t1.c_w_id=2 AND t1.c_d_id=5 and t1.c_last LIKE 'CALLY%'
ORDER BY t1.c_id, t2.o_id, t3.ol_number
;
```
查询结果如下:
```unknow
+------------------+----------------+----------+----------+------------+-----------+-------------+--------------------------+---------+----------------+
| c_first | c_last | c_credit | o_ol_cnt | o_entry_d | ol_number | ol_quantity | i_name | i_price | item_sum_price |
+------------------+----------------+----------+----------+------------+-----------+-------------+--------------------------+---------+----------------+
| wPS9EgAgztLRvSuZ | CALLYABLEOUGHT | GC | 7 | 2020-02-15 | 1 | 5 | FJT8fkxaUh2aUbI | 79.95 | 399.75 |
| wPS9EgAgztLRvSuZ | CALLYABLEOUGHT | GC | 7 | 2020-02-15 | 2 | 5 | kiMk43vd9HidvmwG8x | 58.59 | 292.95 |
| wPS9EgAgztLRvSuZ | CALLYABLEOUGHT | GC | 7 | 2020-02-15 | 3 | 5 | JnJEOLUCjunrKkt4Z1pL | 85.26 | 426.30 |
| wPS9EgAgztLRvSuZ | CALLYABLEOUGHT | GC | 7 | 2020-02-15 | 4 | 5 | CrFVAZW3OhyekdDNc2rPH | 22.30 | 111.50 |
| wPS9EgAgztLRvSuZ | CALLYABLEOUGHT | GC | 7 | 2020-02-15 | 5 | 5 | fJpsyG11EjWIceJWaB | 41.39 | 206.95 |
| wPS9EgAgztLRvSuZ | CALLYABLEOUGHT | GC | 7 | 2020-02-15 | 6 | 5 | shseF8WI1VSPbWfswSsIuNC | 30.04 | 150.20 |
| wPS9EgAgztLRvSuZ | CALLYABLEOUGHT | GC | 7 | 2020-02-15 | 7 | 5 | prjdpUDOxRvAn5WiMVoT85B1 | 18.55 | 92.75 |
+------------------+----------------+----------+----------+------------+-----------+-------------+--------------------------+---------+----------------+
7 rows in set (0.01 sec)
```

View File

@ -0,0 +1,19 @@
锁定查询结果 SELECT FOR UPDATE
=============================================
OceanBase 支持 MVCC 特性,读是快照读,不阻塞写,是 SELECT 语句还有个特殊的用法可以阻塞写。示例如下:
```javascript
obclient> select w_name, w_ytd, w_tax from ware where w_id=1 for update;
+------------+---------+--------+
| w_name | w_ytd | w_tax |
+------------+---------+--------+
| n1P4zYo8OH | 1200.00 | 0.1868 |
+------------+---------+--------+
1 row in set (0.01 sec)
```

View File

@ -0,0 +1,48 @@
查询中使用数值函数
==============================
常用数值函数有:sum(求和)、avg(求平均)、ceil(向上取整)、floor(向下取整)、trunc(数值取整)、round(n)(四舍五入保留n位小数)。
如求历史表中每个仓库和区域的总销售额和平均每单销售额,SQL 如下:
```javascript
SELECT h_w_id, h_d_id, sum(h_amount) sum_h_amount , avg(h_amount) avg_h_amount
FROM hist
GROUP BY h_w_id, h_d_id ;
```
查询结果如下:​![](https://cdn.nlark.com/yuque/0/2020/png/177325/1600744747117-29d3b100-ef57-4f96-bc51-a8f6d026003d.png)
```unknow
​+--------+--------+--------------+--------------+
| h_w_id | h_d_id | sum_h_amount | avg_h_amount |
+--------+--------+--------------+--------------+
| 1 | 1 | 120.00 | 10.000000 |
| 1 | 2 | 120.00 | 10.000000 |
| 1 | 3 | 120.00 | 10.000000 |
| 1 | 4 | 120.00 | 10.000000 |
| 1 | 5 | 120.00 | 10.000000 |
| 1 | 6 | 120.00 | 10.000000 |
| 1 | 7 | 120.00 | 10.000000 |
| 1 | 8 | 120.00 | 10.000000 |
| 1 | 9 | 120.00 | 10.000000 |
| 1 | 10 | 120.00 | 10.000000 |
| 2 | 1 | 120.00 | 10.000000 |
| 2 | 2 | 120.00 | 10.000000 |
| 2 | 3 | 120.00 | 10.000000 |
| 2 | 4 | 120.00 | 10.000000 |
| 2 | 5 | 120.00 | 10.000000 |
| 2 | 6 | 120.00 | 10.000000 |
| 2 | 7 | 120.00 | 10.000000 |
| 2 | 8 | 120.00 | 10.000000 |
| 2 | 9 | 120.00 | 10.000000 |
| 2 | 10 | 120.00 | 10.000000 |
+--------+--------+--------------+--------------+
20 rows in set (0.01 sec)
```

View File

@ -0,0 +1,38 @@
查询中使用字符串连接符
================================
MySQL 租户的字符串连接函数是 concat 、 concat_ws, '\|\|' 默认是表示逻辑运算符\`或\`。
如查看 MySQL 租户下的客户姓名,SQL语句如下:
```javascript
obclient> SELECT concat_ws(' ', c_first, c_last) full_name FROM cust ORDER BY c_last LIMIT 2;
+---------------------------+
| full_name |
+---------------------------+
| fvBZoeIV2uJh7 ABLEABLEESE |
| dHmIgRV1IsC ABLEABLEOUGHT |
+---------------------------+
2 rows in set (0.01 sec)
```
如果把 MySQL 租户下的变量 sql_mode 值增加一个选项 PIPES_AS_CONCAT ,则 '\|\|' 也会当作字符串连接符。SQL语句如下:
```javascript
obclient> SET SESSION sql_mode='PIPES_AS_CONCAT,STRICT_TRANS_TABLES,STRICT_ALL_TABLES';
obclient> SELECT c_first || ' ' || c_last full_name FROM cust ORDER BY c_last LIMIT 2;
+---------------------------+
| full_name |
+---------------------------+
| fvBZoeIV2uJh7 ABLEABLEESE |
| dHmIgRV1IsC ABLEABLEOUGHT |
+---------------------------+
2 rows in set (0.01 sec)
```

View File

@ -0,0 +1,23 @@
查询中使用字符串函数
===============================
常用的字符串函数有求字符串长度(length)、字符串截取(substr)、字符串拼接、 字符串转大小写(upper lower)、字符串删除前后缀(ltrim rtrim trim)。
需要注意的是,在 MySQL 租户里,字符串长度函数(length)长度单位是字节,char_length 函数的字符串长度单位是字符。
```javascript
$obclient -h192.168.1.101 -utpcc@obmysql#obdemo -P2883 -p123456 -A tpccdb
obclient> select length('中'), char_length('中');
+---------------+--------------------+
| length('中') | char_length('中') |
+---------------+--------------------+
| 3 | 1 |
+---------------+--------------------+
1 row in set (0.00 sec)
```

View File

@ -0,0 +1,99 @@
查询中使用时间函数
==============================
MySQL 租户常用的时间类型有 date、timestamp、 time、datetime、year 等,更多时间类型用法,请参考《OceanBase SQL参考(MySQL模式)》。
MySQL 租户常用的取数据库时间函数是 now() ,curdate() 和 curtime() 。
* 示例:格式化时间显示
MySQL 租户调整时间类型显示的格式,可以用date_format 函数,SQL 如下:
```javascript
obclient> select now(), date_format(now(), "%Y/%m/%d %T") new_time ;
+---------------------+---------------------+
| now() | new_time |
+---------------------+---------------------+
| 2020-04-03 15:55:37 | 2020/04/03 15:55:37 |
+---------------------+---------------------+
1 row in set (0.00 sec)
```
* 示例:提取时间中的年/月/日/时/分/秒
MySQL 租户从时间中提取年/月/日/时/分/秒,可以用 extract 函数,SQL如下:
```javascript
obclient> SET @dt = now();
obclient> SELECT @dt
, extract(YEAR FROM @dt) d_year
, extract(MONTH FROM @dt) d_month
, extract(week FROM @dt) d_week
, extract(DAY FROM @dt) d_day
, extract(HOUR FROM @dt) d_hour
, extract(MINUTE FROM @dt) d_min
, extract(SECOND FROM @dt) d_second
, extract(year_month FROM @dt) d_year_month
, extract(hour_minute FROM @dt) d_hour_min
\G
*************************** 1. row ***************************
@dt: 2020-03-27 18:00:52
d_year: 2020
d_month: 3
d_week: 12
d_day: 27
d_hour: 18
d_min: 0
d_second: 52
d_year_month: 202003
d_hour_min: 1800
1 row in set (0.00 sec)
```
* 示例:时间类型加减
MySQL 租户对时间进行加减,可以使用 date_add 或 date_sub 函数,SQL 如下:
```javascript
obclient> SET @dt = now();
obclient> SELECT @dt
, date_add(@dt, INTERVAL 1 DAY ) t1
, date_add(@dt, INTERVAL 1 HOUR ) t2
, date_add(@dt, INTERVAL -10 MINUTE ) t3
, date_add(@dt, INTERVAL -1 MONTH ) t4
, date_sub(@dt, INTERVAL 1 YEAR ) t5
\G
*************************** 1. row ***************************
@dt: 2020-03-27 18:03:44
t1: 2020-03-28 18:03:44
t2: 2020-03-27 19:03:44
t3: 2020-03-27 17:53:44
t4: 2020-02-27 18:03:44
t5: 2019-03-27 18:03:44
1 row in set (0.01 sec)
```

View File

@ -0,0 +1,62 @@
查询中使用类型转换函数
================================
类型转换函数可以将一种数据类型转换为另外一种数据类型,如数值类型和时间类型到字符串类型的相互转换。
* 示例:时间字符串转换为时间类型
MySQL 租户中,时间字符串可以直接复制给 date 类型,MySQL 可以自动转换为时间类型,另外也可以使用 convert 或 cast 函数做类型转换。SQL语句如下:
```javascript
obclient> SELECT CONVERT('2020-02-02 14:30:45', date) t1
, CONVERT('2020-02-02 14:30:45', time) t2
, CONVERT('2020-02-02 14:30:45', datetime) t3
, CAST('2020-02-02 14:30:45' AS date) t4
, CAST('2020-02-02 14:30:45' AS time) t5
, CAST('2020-02-02 14:30:45' AS datetime) t6
\G
*************************** 1. row ***************************
t1: 2020-02-02
t2: 14:30:45
t3: 2020-02-02 14:30:45
t4: 2020-02-02
t5: 14:30:45
t6: 2020-02-02 14:30:45
1 row in set (0.00 sec)
```
MySQL 租户中时间类型转换为字符串类型,可以使用函数 date_format。
* 示例:数值类型和字符串类型互相转换
MySQL 租户中,数值类型和字符串类型互相转换,可以用函数 convert 、cast。
```javascript
obclient> SELECT convert('3.1415926', decimal) n1
, cast('3.1415926' AS decimal) n2
, convert(3.1415926, char(10)) s1
, cast(3.1414926 AS char(10)) s2
;
+------+------+-----------+-----------+
| n1 | n2 | s1 | s2 |
+------+------+-----------+-----------+
| 3 | 3 | 3.1415926 | 3.1414926 |
+------+------+-----------+-----------+
1 row in set (0.00 sec)
```

View File

@ -0,0 +1,78 @@
查询中使用聚合函数
==============================
聚合函数扫描一组记录,然后返回单行记录。这组记录可以是一个表或者视图、或者一个子查询的结果。OceanBase 支持的聚合函数详情请参考手册《OceanBase SQL参考(MySQL模式)》。
聚合函数通常跟 GROUP BY 子句一起使用,按照一个或多个列的值分组,然后每组返回单笔记录。
**示例:分组统计每个仓库的销售额**
MySQL 租户中,聚合函数跟 GROUP BY 子句一起使用的时候,对 select_list 里的列没有要求。这个可能会导致结果集很奇怪。如果要求 select_list 里的列跟 GROUP BY 子句中的列保持一致,需要设置 MySQL 命令行下的 sql_mode 为 'ONLY_FULL_GROUP_BY'。SQL 查询如下:
```javascript
obclient> SELECT ol_w_id
, count(*) order_count
, sum(ol_amount) sum_amount
, round(avg(ol_amount),2) avg_amount
, min(ol_amount) min_amount
,max(ol_amount) max_amount
FROM ordl
GROUP BY ol_w_id
ORDER BY ol_w_id ;
+---------+-------------+------------+------------+------------+------------+
| ol_w_id | order_count | sum_amount | avg_amount | min_amount | max_amount |
+---------+-------------+------------+------------+------------+------------+
| 1 | 297 | 917174.33 | 3088.13 | 0.00 | 9876.11 |
| 2 | 329 | 1153354.23 | 3505.64 | 0.00 | 9979.34 |
+---------+-------------+------------+------------+------------+------------+
2 rows in set (0.01 sec)
obclient> SELECT ol_w_id, ol_d_id
, count(*) order_count
, sum(ol_amount) sum_amount
, round(avg(ol_amount),2) avg_amount
, min(ol_amount) min_amount
, max(ol_amount) max_amount
FROM ordl
GROUP BY ol_w_id
ORDER BY ol_w_id
;
+---------+---------+-------------+------------+------------+------------+------------+
| ol_w_id | ol_d_id | order_count | sum_amount | avg_amount | min_amount | max_amount |
+---------+---------+-------------+------------+------------+------------+------------+
| 1 | 1 | 297 | 917174.33 | 3088.13 | 0.00 | 9876.11 |
| 2 | 1 | 329 | 1153354.23 | 3505.64 | 0.00 | 9979.34 |
+---------+---------+-------------+------------+------------+------------+------------+
2 rows in set (0.00 sec)
obclient> show variables like '%sql_mode%';
+---------------+-------------------------------------------------------+
| Variable_name | Value |
+---------------+-------------------------------------------------------+
| sql_mode | PIPES_AS_CONCAT,STRICT_TRANS_TABLES,STRICT_ALL_TABLES |
+---------------+-------------------------------------------------------+
1 row in set (0.00 sec)
obclient> SET SESSION sql_mode='STRICT_ALL_TABLES,ONLY_FULL_GROUP_BY'; Query OK, 0 rows affected (0.00 sec)
obclient> SELECT ol_w_id, ol_d_id
, count(*) order_count
, sum(ol_amount) sum_amount
, round(avg(ol_amount),2) avg_amount
, min(ol_amount) min_amount
, max(ol_amount) max_amount
FROM ordl
GROUP BY ol_w_id
ORDER BY ol_w_id
;
ERROR 1055 (42000): 'tpccdb.ordl.ol_d_id' is not in GROUP BY
obclient>
```

View File

@ -0,0 +1,36 @@
查询中使用 NULL 相关函数
====================================
NULL 相关的函数用于处理 NULL 值。NULL 值的特点是任何数值都不能等于 NULL 或不等于 NULL,可以通过 IS NULL 判断,也可以使用 NVL 函数将 NULL 值转换为可识别的字符串。下面示例如何识别和转换 NULL 值。
**示例:NULL 值转换**
MySQL 租户中,如果一个列可能有 NULL 值,可以使用 NVL 或 IFNULL 函数探测并转换为特殊字符。SQL查询如下:
```javascript
CREATE TABLE t_null(id number NOT NULL PRIMARY KEY, name varchar(10));
INSERT INTO t_null(id, name) values(1,'A'), (2,NULL), (3,'NULL');
SELECT id, name, nvl(name, 'NOT APPLICABLE') n_name, IFNULL(name, 'NOT APPLICABLE') n2_name
FROM t_null;
```
![](https://cdn.nlark.com/yuque/0/2020/png/177325/1600744842004-cb9ea652-a852-4815-b69f-8bbb274c9c42.png)
执行结果如下:
```unknow
+----+------+----------------+----------------+
| id | name | n_name | n2_name |
+----+------+----------------+----------------+
| 1 | A | A | A |
| 2 | NULL | NOT APPLICABLE | NOT APPLICABLE |
| 3 | NULL | NULL | NULL |
+----+------+----------------+----------------+
3 rows in set (0.01 sec)
```

View File

@ -0,0 +1,94 @@
查询中使用 CASE 函数
==================================
CASE 表达式可以实现类似"IF...ELSE...THEN"的逻辑而不用调用子程序。CASE 表达式有两种使用方法,简单的和带搜索条件的。
* 示例:在查询中使用简单的 CASE 表达式,将国家代码缩写翻译为全称。
```javascript
obclient> CREATE TABLE t_case(id number NOT NULL PRIMARY KEY, abbr varchar(5));
Query OK, 0 rows affected (0.08 sec)
obclient> INSERT INTO t_case(id, abbr) VALUES (1,'US'),(2,'UK'),(3,'CN'),(4,'JP');
Query OK, 4 rows affected (0.02 sec)
Records: 4 Duplicates: 0 Warnings: 0
obclient>
obclient> SELECT id, abbr,
CASE abbr
WHEN 'US' THEN 'America'
WHEN 'UK' THEN 'English'
WHEN 'CN' THEN 'China'
ELSE 'UNKOWN'
END full_name
FROM t_case ;
+----+------+-----------+
| id | abbr | full_name |
+----+------+-----------+
| 1 | US | America |
| 2 | UK | English |
| 3 | CN | China |
| 4 | JP | UNKOWN |
+----+------+-----------+
4 rows in set (0.00 sec)
obclient>
```
* 示例:在查询中使用带搜索条件的 CASE 表达式
```javascript
obclient> DROP TABLE IF EXISTS t_case2;
Query OK, 0 rows affected (0.02 sec)
obclient> CREATE TABLE t_case2(id number NOT NULL PRIMARY KEY, c_date date );
Query OK, 0 rows affected (0.14 sec)
obclient> INSERT INTO t_case2(id,c_date)
VALUES (1,'2019-03-01')
,(2,'2019-05-08')
,(3,'2019-07-07')
,(4,'2019-10-11')
,(5,'2019-12-12')
,(6,'2020-01-05');
Query OK, 6 rows affected (0.01 sec)
Records: 6 Duplicates: 0 Warnings: 0
obclient>
obclient> SELECT id, c_date,
CASE
WHEN datediff(now(), c_date) > 12*30 THEN 'More than one year ago'
WHEN datediff(now(), c_date) > 9*30 THEN 'More than three quarters ago'
WHEN datediff(now(), c_date) > 6*30 THEN 'More than half a year ago'
WHEN datediff(now(), c_date) > 3*30 THEN 'More than a quarter ago'
WHEN datediff(now(), c_date) >= 0 THEN 'Within a quarter'
ELSE 'Illegal'
END "Duration"
FROM t_case2;
+----+------------+------------------------------+
| id | c_date | Duration |
+----+------------+------------------------------+
| 1 | 2019-03-01 | More than one year ago |
| 2 | 2019-05-08 | More than three quarters ago |
| 3 | 2019-07-07 | More than three quarters ago |
| 4 | 2019-10-11 | More than a quarter ago |
| 5 | 2019-12-12 | More than a quarter ago |
| 6 | 2020-01-05 | Within a quarter |
+----+------------+------------------------------+
6 rows in set (0.01 sec)
```

View File

@ -0,0 +1,48 @@
查看查询执行计划
=============================
OceanBase 的 SQL 引擎支持执行计划解析和缓存技术,可以通过分析查询语句的执行计划来分析查询性能。执行计划查看的语法格式如下:
```javascript
explain [extended] query_statment ;
```
**示例:查看查询执行计划**
```javascript
obclient> EXPLAIN select count(*) from stok \G
*************************** 1. row ***************************
Query Plan: ========================================================
|ID|OPERATOR |NAME |EST. ROWS|COST |
--------------------------------------------------------
|0 |SCALAR GROUP BY | |1 |600337|
|1 | PX COORDINATOR | |1 |485729|
|2 | EXCHANGE OUT DISTR |:EX10000|1 |485729|
|3 | MERGE GROUP BY | |1 |485729|
|4 | PX PARTITION ITERATOR| |600000 |371122|
|5 | TABLE SCAN |stok |600000 |371122|
========================================================
Outputs & filters:
-------------------------------------
0 - output([T_FUN_COUNT_SUM(T_FUN_COUNT(*))]), filter(nil),
group(nil), agg_func([T_FUN_COUNT_SUM(T_FUN_COUNT(*))])
1 - output([T_FUN_COUNT(*)]), filter(nil)
2 - output([T_FUN_COUNT(*)]), filter(nil), dop=1
3 - output([T_FUN_COUNT(*)]), filter(nil),
group(nil), agg_func([T_FUN_COUNT(*)])
4 - output([stok.s_i_id]), filter(nil)
5 - output([stok.s_i_id]), filter(nil),
access([stok.s_i_id]), partitions(p[0-5])
```

View File

@ -0,0 +1,87 @@
在查询中使用 SQL Hint
====================================
初次使用 OceanBase 的用户,经常会用大表测试各种查询,有时会感觉性能不是很快,此时需要在查询中使用 SQL Hint。
关于 SQL Hint
--------------------
OceanBase SQL 的执行性能跟 SQL 的执行计划有关,执行计划跟表的连接方式、查询条件和表的索引都有关系,通常这是数据库的 SQL 引擎内部逻辑。通过在 SQL 里添加注释,您可能改变执行计划的内容,从而改变 SQL 的执行性能。SQL Hint 的格式是:
```javascript
/*+ hint_text */
```
常用 SQL Hint 有:
* **read_consistency(weak)** :弱一致性读,指引SQL读取相关表的分区的备副本。
* **index** ( *table_name* , *index_name* ):指引SQL使用某个表的某个索引读取数据。
* **query_timeout(int_num):** 设置当前SQL的查询超时时间,单位是us。
其他常用 SQL Hints 请参考附录 **OceanBase 常用 SQL Hints**
使用 SQL Hint
--------------------
SQL Hint 通常用在 SQL 里,并不限于查询 SQL。这里以查询 SQL 为例,简单的语法格式如下:
```javascript
SELECT /*+ hint_text [, hint_text] */ select_items FROM table_name
```
**说明**
* 多个 SQL Hint 可以叠加使用,注意功能不要冲突。
* 在 obclient 命令行环境下,默认会忽略注释语法,导致 SQL Hint 不起作用,所以启动 obclient 时需要增加参数"-c"。
示例:在查询 SQL 中使用 SQL Hint,下面 SQL 指定查询超时时间为 10 秒。
```javascript
obclient> select /*+ query_timeout(10000000) */ o_id,o_c_id,o_carrier_id,o_ol_cnt,o_all_local,o_entry_d
from ordr
where o_w_id=1 and o_d_id=2 and o_id=2100;
+------+--------+--------------+----------+-------------+------------+
| o_id | o_c_id | o_carrier_id | o_ol_cnt | o_all_local | o_entry_d |
+------+--------+--------------+----------+-------------+------------+
| 2100 | 8 | 8 | 11 | 1 | 2020-02-15 |
+------+--------+--------------+----------+-------------+------------+
1 row in set (0.00 sec)
obclient> SELECT /*+ no_use_px paratLel(8) */ * FROM(
SELECT /*+ no_use_px parallel(8) */ no_w_id, no_d_id, MAX(no_o_id) max_no_o_id, MIN(no_o_id) min_no_o_id, COUNT(*) count_no
FROM nord
GROUP BY no_w_id, no_d_Id
) x
WHERE max_no_o_id - min_no_o_id+ 1!= count_no;
Empty set (0.01 sec)
obclient>
```

View File

@ -0,0 +1,41 @@
关于查询超时设计
=============================
OceanBase 租户内部执行查询的工作线程数跟租户的 CPU 个数相关,所以工作线程是很稀有的资源。如果查询长时间不返回,就会一直占用这个工作线程资源。OceanBase 为避免长时间不返回的查询长期占用工作线程资源以及可能占用 CPU 资源,设计了查询超时功能。这个超时时间默认由租户变量 ob_query_timeout 控制,默认值是100000000(单位微秒)。当查询时间超过这个变量值后,会返回错误-4012(HY000): Timeout 。
默认的超时参数对于 OLTP 类业务来说是合理的,但是对于 OLAP 类业务就不一定。此时可以选择在会话级别调整租户变量的值,或者使用 SQL Hint 设置超时参数。
**示例:设置查询超时**
```javascript
#obclient -h127.1 -uroot@obmysql#obdemo -P3883 -p123456 -c -A
obclient> show variables like 'ob_query_timeout';
+------------------+----------+
| Variable_name | Value |
+------------------+----------+
| ob_query_timeout | 10000000 |
+------------------+----------+
1 row in set (0.01 sec)
obclient> set session ob_query_timeout=10000000;
Query OK, 0 rows affected (0.00 sec)
obclient> select sleep(11);
ERROR 4012 (HY000): Timeout
obclient>
obclient> select /*+ query_timeout(100000000) */ sleep(11);
+-----------+
| sleep(11) |
+-----------+
| 0 |
+-----------+
1 row in set (11.00 sec)
obclient>
```