提交 f9d7a849 编写于 作者: martianzhang's avatar martianzhang

fix bats test case

上级 a0b5adc7
# Query: C3FAEDA6AD6D762B
★ ★ ★ ★ ☆ 95分
```sql
SELECT
*
FROM
film
WHERE
LENGTH = 86
```
## 不建议使用 SELECT * 类型查询
* **Item:** COL.001
* **Severity:** L1
* **Content:** 当表结构变更时,使用 \* 通配符选择所有列将导致查询的含义和行为会发生更改,可能导致查询返回更多的数据。
# Query: E969B9297DA79BA6
★ ★ ★ ★ ☆ 90分
```sql
SELECT
*
FROM
film
WHERE
LENGTH IS NULL
```
## 应尽量避免在 WHERE 子句中对字段进行 NULL 值判断
* **Item:** ARG.006
* **Severity:** L1
* **Content:** 使用 IS NULL 或 IS NOT NULL 将可能导致引擎放弃使用索引而进行全表扫描,如:select id from t where num is null;可以在num上设置默认值0,确保表中 num 列没有 NULL 值,然后这样查询: select id from t where num=0;
## 不建议使用 SELECT * 类型查询
* **Item:** COL.001
* **Severity:** L1
* **Content:** 当表结构变更时,使用 \* 通配符选择所有列将导致查询的含义和行为会发生更改,可能导致查询返回更多的数据。
# Query: 8A106444D14B9880
★ ★ ★ ☆ ☆ 60分
```sql
SELECT
*
FROM
film
HAVING
title = 'abc'
```
## 最外层 SELECT 未指定 WHERE 条件
* **Item:** CLA.001
* **Severity:** L4
* **Content:** SELECT 语句没有 WHERE 子句,可能检查比预期更多的行(全表扫描)。对于 SELECT COUNT(\*) 类型的请求如果不要求精度,建议使用 SHOW TABLE STATUS 或 EXPLAIN 替代。
## 不建议使用 HAVING 子句
* **Item:** CLA.013
* **Severity:** L3
* **Content:** 将查询的 HAVING 子句改写为 WHERE 中的查询条件,可以在查询处理期间使用索引。
## 不建议使用 SELECT * 类型查询
* **Item:** COL.001
* **Severity:** L1
* **Content:** 当表结构变更时,使用 \* 通配符选择所有列将导致查询的含义和行为会发生更改,可能导致查询返回更多的数据。
# Query: A0C5E62C724A121A
★ ★ ★ ★ ☆ 95分
```sql
SELECT
*
FROM
sakila. film
WHERE
LENGTH >= 60
```
## 不建议使用 SELECT * 类型查询
* **Item:** COL.001
* **Severity:** L1
* **Content:** 当表结构变更时,使用 \* 通配符选择所有列将导致查询的含义和行为会发生更改,可能导致查询返回更多的数据。
# Query: 868317D1973FD1B0
★ ★ ★ ★ ☆ 95分
```sql
SELECT
*
FROM
film
WHERE
LENGTH BETWEEN 60
AND 84
```
## 不建议使用 SELECT * 类型查询
* **Item:** COL.001
* **Severity:** L1
* **Content:** 当表结构变更时,使用 \* 通配符选择所有列将导致查询的含义和行为会发生更改,可能导致查询返回更多的数据。
# Query: 707FE669669FA075
★ ★ ★ ★ ☆ 95分
```sql
SELECT
*
FROM
film
WHERE
title LIKE 'AIR%'
```
## 不建议使用 SELECT * 类型查询
* **Item:** COL.001
* **Severity:** L1
* **Content:** 当表结构变更时,使用 \* 通配符选择所有列将导致查询的含义和行为会发生更改,可能导致查询返回更多的数据。
# Query: DF916439ABD07664
★ ★ ★ ★ ☆ 90分
```sql
SELECT
*
FROM
film
WHERE
title IS NOT NULL
```
## 应尽量避免在 WHERE 子句中对字段进行 NULL 值判断
* **Item:** ARG.006
* **Severity:** L1
* **Content:** 使用 IS NULL 或 IS NOT NULL 将可能导致引擎放弃使用索引而进行全表扫描,如:select id from t where num is null;可以在num上设置默认值0,确保表中 num 列没有 NULL 值,然后这样查询: select id from t where num=0;
## 不建议使用 SELECT * 类型查询
* **Item:** COL.001
* **Severity:** L1
* **Content:** 当表结构变更时,使用 \* 通配符选择所有列将导致查询的含义和行为会发生更改,可能导致查询返回更多的数据。
# Query: B9336971FF3D3792
★ ★ ★ ★ ☆ 95分
```sql
SELECT
*
FROM
film
WHERE
LENGTH = 114
AND title = 'ALABAMA DEVIL'
```
## 不建议使用 SELECT * 类型查询
* **Item:** COL.001
* **Severity:** L1
* **Content:** 当表结构变更时,使用 \* 通配符选择所有列将导致查询的含义和行为会发生更改,可能导致查询返回更多的数据。
# Query: 68E48001ECD53152
★ ★ ★ ★ ☆ 95分
```sql
SELECT
*
FROM
film
WHERE
LENGTH > 100
AND title = 'ALABAMA DEVIL'
```
## 不建议使用 SELECT * 类型查询
* **Item:** COL.001
* **Severity:** L1
* **Content:** 当表结构变更时,使用 \* 通配符选择所有列将导致查询的含义和行为会发生更改,可能导致查询返回更多的数据。
# Query: 12FF1DAA3D425FA9
★ ★ ★ ★ ☆ 95分
```sql
SELECT
*
FROM
film
WHERE
LENGTH > 100
AND language_id < 10
AND title = 'xyz'
```
## 不建议使用 SELECT * 类型查询
* **Item:** COL.001
* **Severity:** L1
* **Content:** 当表结构变更时,使用 \* 通配符选择所有列将导致查询的含义和行为会发生更改,可能导致查询返回更多的数据。
# Query: E84CBAAC2E12BDEA
★ ★ ★ ★ ☆ 95分
```sql
SELECT
*
FROM
film
WHERE
LENGTH > 100
AND language_id < 10
```
## 不建议使用 SELECT * 类型查询
* **Item:** COL.001
* **Severity:** L1
* **Content:** 当表结构变更时,使用 \* 通配符选择所有列将导致查询的含义和行为会发生更改,可能导致查询返回更多的数据。
# Query: 6A0F035BD4E01018
★ ★ ★ ★ ☆ 85分
```sql
SELECT
release_year, SUM( LENGTH)
FROM
film
WHERE
LENGTH = 123
AND language_id = 1
GROUP BY
release_year
```
## 请为 GROUP BY 显示添加 ORDER BY 条件
* **Item:** CLA.008
* **Severity:** L2
* **Content:** 默认 MySQL 会对 'GROUP BY col1, col2, ...' 请求按如下顺序排序 'ORDER BY col1, col2, ...'。如果 GROUP BY 语句不指定 ORDER BY 条件会导致无谓的排序产生,如果不需要排序建议添加 'ORDER BY NULL'。
## 使用 SUM(COL) 时需注意 NPE 问题
* **Item:** FUN.006
* **Severity:** L1
* **Content:** 当某一列的值全是 NULL 时,COUNT(COL) 的返回结果为0,但 SUM(COL) 的返回结果为 NULL,因此使用 SUM() 时需注意 NPE 问题。可以使用如下方式来避免 SUM 的 NPE 问题: SELECT IF(ISNULL(SUM(COL)), 0, SUM(COL)) FROM tbl
# Query: 23D176AEA2947002
★ ★ ★ ★ ☆ 85分
```sql
SELECT
release_year, SUM( LENGTH)
FROM
film
WHERE
LENGTH >= 123
GROUP BY
release_year
```
## 请为 GROUP BY 显示添加 ORDER BY 条件
* **Item:** CLA.008
* **Severity:** L2
* **Content:** 默认 MySQL 会对 'GROUP BY col1, col2, ...' 请求按如下顺序排序 'ORDER BY col1, col2, ...'。如果 GROUP BY 语句不指定 ORDER BY 条件会导致无谓的排序产生,如果不需要排序建议添加 'ORDER BY NULL'。
## 使用 SUM(COL) 时需注意 NPE 问题
* **Item:** FUN.006
* **Severity:** L1
* **Content:** 当某一列的值全是 NULL 时,COUNT(COL) 的返回结果为0,但 SUM(COL) 的返回结果为 NULL,因此使用 SUM() 时需注意 NPE 问题。可以使用如下方式来避免 SUM 的 NPE 问题: SELECT IF(ISNULL(SUM(COL)), 0, SUM(COL)) FROM tbl
# Query: 73DDF6E6D9E40384
★ ★ ★ ☆ ☆ 65分
```sql
SELECT
release_year, language_id, SUM( LENGTH)
FROM
film
GROUP BY
release_year, language_id
```
## 最外层 SELECT 未指定 WHERE 条件
* **Item:** CLA.001
* **Severity:** L4
* **Content:** SELECT 语句没有 WHERE 子句,可能检查比预期更多的行(全表扫描)。对于 SELECT COUNT(\*) 类型的请求如果不要求精度,建议使用 SHOW TABLE STATUS 或 EXPLAIN 替代。
## 请为 GROUP BY 显示添加 ORDER BY 条件
* **Item:** CLA.008
* **Severity:** L2
* **Content:** 默认 MySQL 会对 'GROUP BY col1, col2, ...' 请求按如下顺序排序 'ORDER BY col1, col2, ...'。如果 GROUP BY 语句不指定 ORDER BY 条件会导致无谓的排序产生,如果不需要排序建议添加 'ORDER BY NULL'。
## 使用 SUM(COL) 时需注意 NPE 问题
* **Item:** FUN.006
* **Severity:** L1
* **Content:** 当某一列的值全是 NULL 时,COUNT(COL) 的返回结果为0,但 SUM(COL) 的返回结果为 NULL,因此使用 SUM() 时需注意 NPE 问题。可以使用如下方式来避免 SUM 的 NPE 问题: SELECT IF(ISNULL(SUM(COL)), 0, SUM(COL)) FROM tbl
# Query: B3C502B4AA344196
★ ★ ★ ☆ ☆ 75分
```sql
SELECT
release_year, SUM( LENGTH)
FROM
film
WHERE
LENGTH = 123
GROUP BY
release_year, (LENGTH+ language_id)
```
## 请为 GROUP BY 显示添加 ORDER BY 条件
* **Item:** CLA.008
* **Severity:** L2
* **Content:** 默认 MySQL 会对 'GROUP BY col1, col2, ...' 请求按如下顺序排序 'ORDER BY col1, col2, ...'。如果 GROUP BY 语句不指定 ORDER BY 条件会导致无谓的排序产生,如果不需要排序建议添加 'ORDER BY NULL'。
## GROUP BY 的条件为表达式
* **Item:** CLA.010
* **Severity:** L2
* **Content:** 当 GROUP BY 条件为表达式或函数时会使用到临时表,如果在未指定 WHERE 或 WHERE 条件返回的结果集较大时性能会很差。
## 使用 SUM(COL) 时需注意 NPE 问题
* **Item:** FUN.006
* **Severity:** L1
* **Content:** 当某一列的值全是 NULL 时,COUNT(COL) 的返回结果为0,但 SUM(COL) 的返回结果为 NULL,因此使用 SUM() 时需注意 NPE 问题。可以使用如下方式来避免 SUM 的 NPE 问题: SELECT IF(ISNULL(SUM(COL)), 0, SUM(COL)) FROM tbl
# Query: 47044E1FE1A965A5
★ ★ ★ ☆ ☆ 70分
```sql
SELECT
release_year, SUM( film_id)
FROM
film
GROUP BY
release_year
```
## 最外层 SELECT 未指定 WHERE 条件
* **Item:** CLA.001
* **Severity:** L4
* **Content:** SELECT 语句没有 WHERE 子句,可能检查比预期更多的行(全表扫描)。对于 SELECT COUNT(\*) 类型的请求如果不要求精度,建议使用 SHOW TABLE STATUS 或 EXPLAIN 替代。
## 请为 GROUP BY 显示添加 ORDER BY 条件
* **Item:** CLA.008
* **Severity:** L2
* **Content:** 默认 MySQL 会对 'GROUP BY col1, col2, ...' 请求按如下顺序排序 'ORDER BY col1, col2, ...'。如果 GROUP BY 语句不指定 ORDER BY 条件会导致无谓的排序产生,如果不需要排序建议添加 'ORDER BY NULL'。
# Query: 2BA1217F6C8CF0AB
★ ★ ☆ ☆ ☆ 45分
```sql
SELECT
*
FROM
address
GROUP BY
address, district
```
## 最外层 SELECT 未指定 WHERE 条件
* **Item:** CLA.001
* **Severity:** L4
* **Content:** SELECT 语句没有 WHERE 子句,可能检查比预期更多的行(全表扫描)。对于 SELECT COUNT(\*) 类型的请求如果不要求精度,建议使用 SHOW TABLE STATUS 或 EXPLAIN 替代。
## 请为 GROUP BY 显示添加 ORDER BY 条件
* **Item:** CLA.008
* **Severity:** L2
* **Content:** 默认 MySQL 会对 'GROUP BY col1, col2, ...' 请求按如下顺序排序 'ORDER BY col1, col2, ...'。如果 GROUP BY 语句不指定 ORDER BY 条件会导致无谓的排序产生,如果不需要排序建议添加 'ORDER BY NULL'。
## 不建议使用 SELECT * 类型查询
* **Item:** COL.001
* **Severity:** L1
* **Content:** 当表结构变更时,使用 \* 通配符选择所有列将导致查询的含义和行为会发生更改,可能导致查询返回更多的数据。
## 非确定性的 GROUP BY
* **Item:** RES.001
* **Severity:** L4
* **Content:** SQL返回的列既不在聚合函数中也不是 GROUP BY 表达式的列中,因此这些值的结果将是非确定性的。如:select a, b, c from tbl where foo="bar" group by a,该 SQL 返回的结果就是不确定的。
# Query: 863A85207E4F410D
★ ★ ★ ★ ☆ 80分
```sql
SELECT
title
FROM
film
WHERE
ABS( language_id) = 3
GROUP BY
title
```
## 请为 GROUP BY 显示添加 ORDER BY 条件
* **Item:** CLA.008
* **Severity:** L2
* **Content:** 默认 MySQL 会对 'GROUP BY col1, col2, ...' 请求按如下顺序排序 'ORDER BY col1, col2, ...'。如果 GROUP BY 语句不指定 ORDER BY 条件会导致无谓的排序产生,如果不需要排序建议添加 'ORDER BY NULL'。
## 避免在 WHERE 条件中使用函数或其他运算符
* **Item:** FUN.001
* **Severity:** L2
* **Content:** 虽然在 SQL 中使用函数可以简化很多复杂的查询,但使用了函数的查询无法利用表中已经建立的索引,该查询将会是全表扫描,性能较差。通常建议将列名写在比较运算符左侧,将查询过滤条件放在比较运算符右侧。也不建议在查询比较条件两侧书写多余的括号,这会对阅读产生比较大的困扰。
# Query: DF59FD602E4AA368
★ ★ ★ ★ ☆ 80分
```sql
SELECT
language_id
FROM
film
WHERE
LENGTH = 123
GROUP BY
release_year
ORDER BY
language_id
```
## 非确定性的 GROUP BY
* **Item:** RES.001
* **Severity:** L4
* **Content:** SQL返回的列既不在聚合函数中也不是 GROUP BY 表达式的列中,因此这些值的结果将是非确定性的。如:select a, b, c from tbl where foo="bar" group by a,该 SQL 返回的结果就是不确定的。
# Query: F6DBEAA606D800FC
★ ★ ★ ★ ★ 100分
```sql
SELECT
release_year
FROM
film
WHERE
LENGTH = 123
GROUP BY
release_year
ORDER BY
release_year
```
## OK
# Query: 6E9B96CA3F0E6BDA
★ ★ ★ ☆ ☆ 65分
```sql
SELECT
*
FROM
film
WHERE
LENGTH = 123
ORDER BY
release_year ASC, language_id DESC
```
## ORDER BY 语句对多个不同条件使用不同方向的排序无法使用索引
* **Item:** CLA.007
* **Severity:** L2
* **Content:** ORDER BY 子句中的所有表达式必须按统一的 ASC 或 DESC 方向排序,以便利用索引。
## 不建议使用 SELECT * 类型查询
* **Item:** COL.001
* **Severity:** L1
* **Content:** 当表结构变更时,使用 \* 通配符选择所有列将导致查询的含义和行为会发生更改,可能导致查询返回更多的数据。
## ORDER BY 多个列但排序方向不同时可能无法使用索引
* **Item:** KEY.008
* **Severity:** L4
* **Content:** 在 MySQL 8.0之前当 ORDER BY 多个列指定的排序方向不同时将无法使用已经建立的索引。
# Query: 2EAACFD7030EA528
★ ★ ★ ★ ★ 100分
```sql
SELECT
release_year
FROM
film
WHERE
LENGTH = 123
GROUP BY
release_year
ORDER BY
release_year
LIMIT
10
```
## OK
# Query: 5CE2F187DBF2A710
★ ★ ★ ★ ☆ 95分
```sql
SELECT
*
FROM
film
WHERE
LENGTH = 123
ORDER BY
release_year
LIMIT
10
```
## 不建议使用 SELECT * 类型查询
* **Item:** COL.001
* **Severity:** L1
* **Content:** 当表结构变更时,使用 \* 通配符选择所有列将导致查询的含义和行为会发生更改,可能导致查询返回更多的数据。
# Query: E75234155B5E2E14
★ ★ ★ ☆ ☆ 75分
```sql
SELECT
*
FROM
film
ORDER BY
release_year
LIMIT
10
```
## 最外层 SELECT 未指定 WHERE 条件
* **Item:** CLA.001
* **Severity:** L4
* **Content:** SELECT 语句没有 WHERE 子句,可能检查比预期更多的行(全表扫描)。对于 SELECT COUNT(\*) 类型的请求如果不要求精度,建议使用 SHOW TABLE STATUS 或 EXPLAIN 替代。
## 不建议使用 SELECT * 类型查询
* **Item:** COL.001
* **Severity:** L1
* **Content:** 当表结构变更时,使用 \* 通配符选择所有列将导致查询的含义和行为会发生更改,可能导致查询返回更多的数据。
# Query: AFEEBF10A8D74E32
★ ★ ★ ★ ☆ 80分
```sql
SELECT
film_id
FROM
film
ORDER BY
release_year
LIMIT
10
```
## 最外层 SELECT 未指定 WHERE 条件
* **Item:** CLA.001
* **Severity:** L4
* **Content:** SELECT 语句没有 WHERE 子句,可能检查比预期更多的行(全表扫描)。对于 SELECT COUNT(\*) 类型的请求如果不要求精度,建议使用 SHOW TABLE STATUS 或 EXPLAIN 替代。
# Query: 965D5AC955824512
★ ★ ★ ★ ☆ 95分
```sql
SELECT
*
FROM
film
WHERE
LENGTH > 100
ORDER BY
LENGTH
LIMIT
10
```
## 不建议使用 SELECT * 类型查询
* **Item:** COL.001
* **Severity:** L1
* **Content:** 当表结构变更时,使用 \* 通配符选择所有列将导致查询的含义和行为会发生更改,可能导致查询返回更多的数据。
# Query: 1E2CF4145EE706A5
★ ★ ★ ★ ☆ 95分
```sql
SELECT
*
FROM
film
WHERE
LENGTH < 100
ORDER BY
LENGTH
LIMIT
10
```
## 不建议使用 SELECT * 类型查询
* **Item:** COL.001
* **Severity:** L1
* **Content:** 当表结构变更时,使用 \* 通配符选择所有列将导致查询的含义和行为会发生更改,可能导致查询返回更多的数据。
# Query: A314542EEE8571EE
★ ★ ★ ★ ☆ 95分
```sql
SELECT
*
FROM
customer
WHERE
address_id in (224, 510)
ORDER BY
last_name
```
## 不建议使用 SELECT * 类型查询
* **Item:** COL.001
* **Severity:** L1
* **Content:** 当表结构变更时,使用 \* 通配符选择所有列将导致查询的含义和行为会发生更改,可能导致查询返回更多的数据。
# Query: 0BE2D79E2F1E7CB0
★ ★ ★ ★ ☆ 95分
```sql
SELECT
*
FROM
film
WHERE
release_year = 2016
AND LENGTH != 1
ORDER BY
title
```
## 不建议使用 SELECT * 类型查询
* **Item:** COL.001
* **Severity:** L1
* **Content:** 当表结构变更时,使用 \* 通配符选择所有列将导致查询的含义和行为会发生更改,可能导致查询返回更多的数据。
## '!=' 运算符是非标准的
* **Item:** STA.001
* **Severity:** L0
* **Content:** "<>"才是标准SQL中的不等于运算符。
# Query: 4E73AA068370E6A8
★ ★ ★ ★ ★ 100分
```sql
SELECT
title
FROM
film
WHERE
release_year = 1995
```
## OK
# Query: BA7111449E4F1122
★ ★ ★ ★ ★ 100分
```sql
SELECT
title, replacement_cost
FROM
film
WHERE
language_id = 5
AND LENGTH = 70
```
## OK
# Query: B13E0ACEAF8F3119
★ ★ ★ ★ ★ 100分
```sql
SELECT
title
FROM
film
WHERE
language_id > 5
AND LENGTH > 70
```
## OK
# Query: A3FAB6027484B88B
★ ★ ★ ★ ☆ 95分
```sql
SELECT
*
FROM
film
WHERE
LENGTH = 100
AND title = 'xyz'
ORDER BY
release_year
```
## 不建议使用 SELECT * 类型查询
* **Item:** COL.001
* **Severity:** L1
* **Content:** 当表结构变更时,使用 \* 通配符选择所有列将导致查询的含义和行为会发生更改,可能导致查询返回更多的数据。
# Query: CB42080E9F35AB07
★ ★ ★ ★ ☆ 95分
```sql
SELECT
*
FROM
film
WHERE
LENGTH > 100
AND title = 'xyz'
ORDER BY
release_year
```
## 不建议使用 SELECT * 类型查询
* **Item:** COL.001
* **Severity:** L1
* **Content:** 当表结构变更时,使用 \* 通配符选择所有列将导致查询的含义和行为会发生更改,可能导致查询返回更多的数据。
# Query: C4A212A42400411D
★ ★ ★ ★ ☆ 95分
```sql
SELECT
*
FROM
film
WHERE
LENGTH > 100
ORDER BY
release_year
```
## 不建议使用 SELECT * 类型查询
* **Item:** COL.001
* **Severity:** L1
* **Content:** 当表结构变更时,使用 \* 通配符选择所有列将导致查询的含义和行为会发生更改,可能导致查询返回更多的数据。
# Query: 4ECCA9568BE69E68
★ ★ ★ ☆ ☆ 75分
```sql
SELECT
*
FROM
city a
INNER JOIN country b ON a. country_id= b. country_id
```
## 建议使用 AS 关键字显示声明一个别名
* **Item:** ALI.001
* **Severity:** L0
* **Content:** 在列或表别名(如"tbl AS alias")中, 明确使用 AS 关键字比隐含别名(如"tbl alias")更易懂。
## 最外层 SELECT 未指定 WHERE 条件
* **Item:** CLA.001
* **Severity:** L4
* **Content:** SELECT 语句没有 WHERE 子句,可能检查比预期更多的行(全表扫描)。对于 SELECT COUNT(\*) 类型的请求如果不要求精度,建议使用 SHOW TABLE STATUS 或 EXPLAIN 替代。
## 不建议使用 SELECT * 类型查询
* **Item:** COL.001
* **Severity:** L1
* **Content:** 当表结构变更时,使用 \* 通配符选择所有列将导致查询的含义和行为会发生更改,可能导致查询返回更多的数据。
# Query: 485D56FC88BBBDB9
★ ★ ★ ☆ ☆ 75分
```sql
SELECT
*
FROM
city a
LEFT JOIN country b ON a. country_id= b. country_id
```
## 建议使用 AS 关键字显示声明一个别名
* **Item:** ALI.001
* **Severity:** L0
* **Content:** 在列或表别名(如"tbl AS alias")中, 明确使用 AS 关键字比隐含别名(如"tbl alias")更易懂。
## 最外层 SELECT 未指定 WHERE 条件
* **Item:** CLA.001
* **Severity:** L4
* **Content:** SELECT 语句没有 WHERE 子句,可能检查比预期更多的行(全表扫描)。对于 SELECT COUNT(\*) 类型的请求如果不要求精度,建议使用 SHOW TABLE STATUS 或 EXPLAIN 替代。
## 不建议使用 SELECT * 类型查询
* **Item:** COL.001
* **Severity:** L1
* **Content:** 当表结构变更时,使用 \* 通配符选择所有列将导致查询的含义和行为会发生更改,可能导致查询返回更多的数据。
# Query: 0D0DABACEDFF5765
★ ★ ★ ☆ ☆ 75分
```sql
SELECT
*
FROM
city a
RIGHT JOIN country b ON a. country_id= b. country_id
```
## 建议使用 AS 关键字显示声明一个别名
* **Item:** ALI.001
* **Severity:** L0
* **Content:** 在列或表别名(如"tbl AS alias")中, 明确使用 AS 关键字比隐含别名(如"tbl alias")更易懂。
## 最外层 SELECT 未指定 WHERE 条件
* **Item:** CLA.001
* **Severity:** L4
* **Content:** SELECT 语句没有 WHERE 子句,可能检查比预期更多的行(全表扫描)。对于 SELECT COUNT(\*) 类型的请求如果不要求精度,建议使用 SHOW TABLE STATUS 或 EXPLAIN 替代。
## 不建议使用 SELECT * 类型查询
* **Item:** COL.001
* **Severity:** L1
* **Content:** 当表结构变更时,使用 \* 通配符选择所有列将导致查询的含义和行为会发生更改,可能导致查询返回更多的数据。
# Query: 1E56C6CCEA2131CC
★ ★ ★ ★ ☆ 90分
```sql
SELECT
*
FROM
city a
LEFT JOIN country b ON a. country_id= b. country_id
WHERE
b. last_update IS NULL
```
## 建议使用 AS 关键字显示声明一个别名
* **Item:** ALI.001
* **Severity:** L0
* **Content:** 在列或表别名(如"tbl AS alias")中, 明确使用 AS 关键字比隐含别名(如"tbl alias")更易懂。
## 应尽量避免在 WHERE 子句中对字段进行 NULL 值判断
* **Item:** ARG.006
* **Severity:** L1
* **Content:** 使用 IS NULL 或 IS NOT NULL 将可能导致引擎放弃使用索引而进行全表扫描,如:select id from t where num is null;可以在num上设置默认值0,确保表中 num 列没有 NULL 值,然后这样查询: select id from t where num=0;
## 不建议使用 SELECT * 类型查询
* **Item:** COL.001
* **Severity:** L1
* **Content:** 当表结构变更时,使用 \* 通配符选择所有列将导致查询的含义和行为会发生更改,可能导致查询返回更多的数据。
# Query: F5D30BCAC1E206A1
★ ★ ★ ★ ☆ 90分
```sql
SELECT
*
FROM
city a
RIGHT JOIN country b ON a. country_id= b. country_id
WHERE
a. last_update IS NULL
```
## 建议使用 AS 关键字显示声明一个别名
* **Item:** ALI.001
* **Severity:** L0
* **Content:** 在列或表别名(如"tbl AS alias")中, 明确使用 AS 关键字比隐含别名(如"tbl alias")更易懂。
## 应尽量避免在 WHERE 子句中对字段进行 NULL 值判断
* **Item:** ARG.006
* **Severity:** L1
* **Content:** 使用 IS NULL 或 IS NOT NULL 将可能导致引擎放弃使用索引而进行全表扫描,如:select id from t where num is null;可以在num上设置默认值0,确保表中 num 列没有 NULL 值,然后这样查询: select id from t where num=0;
## 不建议使用 SELECT * 类型查询
* **Item:** COL.001
* **Severity:** L1
* **Content:** 当表结构变更时,使用 \* 通配符选择所有列将导致查询的含义和行为会发生更改,可能导致查询返回更多的数据。
# Query: 17D5BCF21DC2364C
★ ★ ★ ☆ ☆ 65分
```sql
SELECT
*
FROM
city a
LEFT JOIN country b ON a. country_id= b. country_id
UNION
SELECT
*
FROM
city a
RIGHT JOIN country b ON a. country_id= b. country_id
```
## 建议使用 AS 关键字显示声明一个别名
* **Item:** ALI.001
* **Severity:** L0
* **Content:** 在列或表别名(如"tbl AS alias")中, 明确使用 AS 关键字比隐含别名(如"tbl alias")更易懂。
## 最外层 SELECT 未指定 WHERE 条件
* **Item:** CLA.001
* **Severity:** L4
* **Content:** SELECT 语句没有 WHERE 子句,可能检查比预期更多的行(全表扫描)。对于 SELECT COUNT(\*) 类型的请求如果不要求精度,建议使用 SHOW TABLE STATUS 或 EXPLAIN 替代。
## 不建议使用 SELECT * 类型查询
* **Item:** COL.001
* **Severity:** L1
* **Content:** 当表结构变更时,使用 \* 通配符选择所有列将导致查询的含义和行为会发生更改,可能导致查询返回更多的数据。
## 如果您不在乎重复的话,建议使用 UNION ALL 替代 UNION
* **Item:** SUB.002
* **Severity:** L2
* **Content:** 与去除重复的UNION不同,UNION ALL允许重复元组。如果您不关心重复元组,那么使用UNION ALL将是一个更快的选项。
# Query: A4911095C201896F
★ ★ ★ ★ ☆ 85分
```sql
SELECT
*
FROM
city a
RIGHT JOIN country b ON a. country_id= b. country_id
WHERE
a. last_update IS NULL
UNION
SELECT
*
FROM
city a
LEFT JOIN country b ON a. country_id= b. country_id
WHERE
b. last_update IS NULL
```
## 建议使用 AS 关键字显示声明一个别名
* **Item:** ALI.001
* **Severity:** L0
* **Content:** 在列或表别名(如"tbl AS alias")中, 明确使用 AS 关键字比隐含别名(如"tbl alias")更易懂。
## 不建议使用 SELECT * 类型查询
* **Item:** COL.001
* **Severity:** L1
* **Content:** 当表结构变更时,使用 \* 通配符选择所有列将导致查询的含义和行为会发生更改,可能导致查询返回更多的数据。
## 如果您不在乎重复的话,建议使用 UNION ALL 替代 UNION
* **Item:** SUB.002
* **Severity:** L2
* **Content:** 与去除重复的UNION不同,UNION ALL允许重复元组。如果您不关心重复元组,那么使用UNION ALL将是一个更快的选项。
# Query: 3FF20E28EC9CBEF9
★ ★ ★ ★ ☆ 80分
```sql
SELECT
country_id, last_update
FROM
city NATURAL
JOIN country
```
## 最外层 SELECT 未指定 WHERE 条件
* **Item:** CLA.001
* **Severity:** L4
* **Content:** SELECT 语句没有 WHERE 子句,可能检查比预期更多的行(全表扫描)。对于 SELECT COUNT(\*) 类型的请求如果不要求精度,建议使用 SHOW TABLE STATUS 或 EXPLAIN 替代。
# Query: 5C547F08EADBB131
★ ★ ★ ★ ☆ 80分
```sql
SELECT
country_id, last_update
FROM
city NATURAL
LEFT JOIN country
```
## 最外层 SELECT 未指定 WHERE 条件
* **Item:** CLA.001
* **Severity:** L4
* **Content:** SELECT 语句没有 WHERE 子句,可能检查比预期更多的行(全表扫描)。对于 SELECT COUNT(\*) 类型的请求如果不要求精度,建议使用 SHOW TABLE STATUS 或 EXPLAIN 替代。
# Query: AF0C1EB58B23D2FA
★ ★ ★ ★ ☆ 80分
```sql
SELECT
country_id, last_update
FROM
city NATURAL
RIGHT JOIN country
```
## 最外层 SELECT 未指定 WHERE 条件
* **Item:** CLA.001
* **Severity:** L4
* **Content:** SELECT 语句没有 WHERE 子句,可能检查比预期更多的行(全表扫描)。对于 SELECT COUNT(\*) 类型的请求如果不要求精度,建议使用 SHOW TABLE STATUS 或 EXPLAIN 替代。
# Query: 626571EAE84E2C8A
★ ★ ★ ★ ☆ 80分
```sql
SELECT
a. country_id, a. last_update
FROM
city a STRAIGHT_JOIN country b ON a. country_id= b. country_id
```
## 建议使用 AS 关键字显示声明一个别名
* **Item:** ALI.001
* **Severity:** L0
* **Content:** 在列或表别名(如"tbl AS alias")中, 明确使用 AS 关键字比隐含别名(如"tbl alias")更易懂。
## 最外层 SELECT 未指定 WHERE 条件
* **Item:** CLA.001
* **Severity:** L4
* **Content:** SELECT 语句没有 WHERE 子句,可能检查比预期更多的行(全表扫描)。对于 SELECT COUNT(\*) 类型的请求如果不要求精度,建议使用 SHOW TABLE STATUS 或 EXPLAIN 替代。
# Query: 50F2AB4243CE2071
★ ★ ★ ☆ ☆ 60分
```sql
SELECT
a. address, a. postal_code
FROM
sakila. address a
WHERE
a. city_id IN (
SELECT
c. city_id
FROM
sakila. city c)
```
## 建议使用 AS 关键字显示声明一个别名
* **Item:** ALI.001
* **Severity:** L0
* **Content:** 在列或表别名(如"tbl AS alias")中, 明确使用 AS 关键字比隐含别名(如"tbl alias")更易懂。
## 最外层 SELECT 未指定 WHERE 条件
* **Item:** CLA.001
* **Severity:** L4
* **Content:** SELECT 语句没有 WHERE 子句,可能检查比预期更多的行(全表扫描)。对于 SELECT COUNT(\*) 类型的请求如果不要求精度,建议使用 SHOW TABLE STATUS 或 EXPLAIN 替代。
## MySQL 对子查询的优化效果不佳
* **Item:** SUB.001
* **Severity:** L4
* **Content:** MySQL 将外部查询中的每一行作为依赖子查询执行子查询。 这是导致严重性能问题的常见原因。这可能会在 MySQL 5.6 版本中得到改善, 但对于5.1及更早版本, 建议将该类查询分别重写为 JOIN 或 LEFT OUTER JOIN。
# Query: 584CCEC8069B6947
★ ★ ☆ ☆ ☆ 40分
```sql
SELECT
city
FROM(
SELECT
city_id
FROM
city
WHERE
city = "A Corua (La Corua)"
ORDER BY
last_update DESC
LIMIT
50, 10) I
JOIN city ON (I. city_id = city. city_id)
JOIN country ON (country. country_id = city. country_id)
ORDER BY
city DESC
```
## 最外层 SELECT 未指定 WHERE 条件
* **Item:** CLA.001
* **Severity:** L4
* **Content:** SELECT 语句没有 WHERE 子句,可能检查比预期更多的行(全表扫描)。对于 SELECT COUNT(\*) 类型的请求如果不要求精度,建议使用 SHOW TABLE STATUS 或 EXPLAIN 替代。
## 同一张表被连接两次
* **Item:** JOI.002
* **Severity:** L4
* **Content:** 相同的表在 FROM 子句中至少出现两次,可以简化为对该表的单次访问。
## MySQL 对子查询的优化效果不佳
* **Item:** SUB.001
* **Severity:** L4
* **Content:** MySQL 将外部查询中的每一行作为依赖子查询执行子查询。 这是导致严重性能问题的常见原因。这可能会在 MySQL 5.6 版本中得到改善, 但对于5.1及更早版本, 建议将该类查询分别重写为 JOIN 或 LEFT OUTER JOIN。
# Query: 7F02E23D44A38A6D
★ ★ ★ ★ ☆ 80分
```sql
DELETE city, country
FROM
city
INNER JOIN country using (country_id)
WHERE
city. city_id = 1
```
## 不建议使用联表删除或更新
* **Item:** JOI.007
* **Severity:** L4
* **Content:** 当需要同时删除或更新多张表时建议使用简单语句,一条 SQL 只删除或更新一张表,尽量不要将多张表的操作在同一条语句。
## 使用DELETE/DROP/TRUNCATE等操作时注意备份
* **Item:** SEC.003
* **Severity:** L0
* **Content:** 在执行高危操作之前对数据进行备份是十分有必要的。
# Query: F8314ABD1CBF2FF1
★ ★ ★ ★ ☆ 80分
```sql
DELETE city
FROM
city
LEFT JOIN country ON city. country_id = country. country_id
WHERE
country. country IS NULL
```
## 不建议使用联表删除或更新
* **Item:** JOI.007
* **Severity:** L4
* **Content:** 当需要同时删除或更新多张表时建议使用简单语句,一条 SQL 只删除或更新一张表,尽量不要将多张表的操作在同一条语句。
## 使用DELETE/DROP/TRUNCATE等操作时注意备份
* **Item:** SEC.003
* **Severity:** L0
* **Content:** 在执行高危操作之前对数据进行备份是十分有必要的。
# Query: 1A53649C43122975
★ ★ ★ ★ ☆ 80分
```sql
DELETE a1, a2
FROM
city AS a1
INNER JOIN country AS a2
WHERE
a1. country_id= a2. country_id
```
## 不建议使用联表删除或更新
* **Item:** JOI.007
* **Severity:** L4
* **Content:** 当需要同时删除或更新多张表时建议使用简单语句,一条 SQL 只删除或更新一张表,尽量不要将多张表的操作在同一条语句。
## 使用DELETE/DROP/TRUNCATE等操作时注意备份
* **Item:** SEC.003
* **Severity:** L0
* **Content:** 在执行高危操作之前对数据进行备份是十分有必要的。
# Query: B862978586C6338B
★ ★ ★ ★ ☆ 80分
```sql
DELETE FROM
a1, a2 USING city AS a1
INNER JOIN country AS a2
WHERE
a1. country_id= a2. country_id
```
## 不建议使用联表删除或更新
* **Item:** JOI.007
* **Severity:** L4
* **Content:** 当需要同时删除或更新多张表时建议使用简单语句,一条 SQL 只删除或更新一张表,尽量不要将多张表的操作在同一条语句。
## 使用DELETE/DROP/TRUNCATE等操作时注意备份
* **Item:** SEC.003
* **Severity:** L0
* **Content:** 在执行高危操作之前对数据进行备份是十分有必要的。
# Query: F16FD63381EF8299
★ ★ ★ ★ ★ 100分
```sql
DELETE FROM
film
WHERE
LENGTH > 100
```
## 使用DELETE/DROP/TRUNCATE等操作时注意备份
* **Item:** SEC.003
* **Severity:** L0
* **Content:** 在执行高危操作之前对数据进行备份是十分有必要的。
# Query: 08CFE41C7D20AAC8
★ ★ ★ ★ ☆ 80分
```sql
UPDATE
city
INNER JOIN country USING( country_id)
SET
city. city = 'Abha',
city. last_update = '2006-02-15 04:45:25',
country. country = 'Afghanistan'
WHERE
city. city_id= 10
```
## 不建议使用联表删除或更新
* **Item:** JOI.007
* **Severity:** L4
* **Content:** 当需要同时删除或更新多张表时建议使用简单语句,一条 SQL 只删除或更新一张表,尽量不要将多张表的操作在同一条语句。
# Query: C15BDF2C73B5B7ED
★ ★ ★ ★ ☆ 80分
```sql
UPDATE
city
INNER JOIN country ON city. country_id = country. country_id
INNER JOIN address ON city. city_id = address. city_id
SET
city. city = 'Abha',
city. last_update = '2006-02-15 04:45:25',
country. country = 'Afghanistan'
WHERE
city. city_id= 10
```
## 不建议使用联表删除或更新
* **Item:** JOI.007
* **Severity:** L4
* **Content:** 当需要同时删除或更新多张表时建议使用简单语句,一条 SQL 只删除或更新一张表,尽量不要将多张表的操作在同一条语句。
# Query: FCD1ABF36F8CDAD7
★ ★ ★ ★ ★ 100分
```sql
UPDATE
city, country
SET
city. city = 'Abha',
city. last_update = '2006-02-15 04:45:25',
country. country = 'Afghanistan'
WHERE
city. country_id = country. country_id
AND city. city_id= 10
```
## OK
# Query: FE409EB794EE91CF
★ ★ ★ ★ ★ 100分
```sql
UPDATE
film
SET
LENGTH = 10
WHERE
language_id = 20
```
## OK
# Query: 3656B13CC4F888E2
★ ★ ★ ☆ ☆ 65分
```sql
INSERT INTO city (country_id)
SELECT
country_id
FROM
country
```
## 最外层 SELECT 未指定 WHERE 条件
* **Item:** CLA.001
* **Severity:** L4
* **Content:** SELECT 语句没有 WHERE 子句,可能检查比预期更多的行(全表扫描)。对于 SELECT COUNT(\*) 类型的请求如果不要求精度,建议使用 SHOW TABLE STATUS 或 EXPLAIN 替代。
## INSERT INTO xx SELECT 加锁粒度较大请谨慎
* **Item:** LCK.001
* **Severity:** L3
* **Content:** INSERT INTO xx SELECT 加锁粒度较大请谨慎
# Query: 2F7439623B712317
★ ★ ★ ★ ★ 100分
```sql
INSERT INTO city (country_id)
VALUES
(1),
(2),
(3)
```
## OK
# Query: 11EC7AAACC97DC0F
★ ★ ★ ★ ☆ 85分
```sql
INSERT INTO city (country_id)
SELECT
10
FROM
DUAL
```
## INSERT INTO xx SELECT 加锁粒度较大请谨慎
* **Item:** LCK.001
* **Severity:** L3
* **Content:** INSERT INTO xx SELECT 加锁粒度较大请谨慎
# Query: E3DDA1A929236E72
★ ★ ★ ☆ ☆ 65分
```sql
REPLACE INTO city (country_id)
SELECT
country_id
FROM
country
```
## 最外层 SELECT 未指定 WHERE 条件
* **Item:** CLA.001
* **Severity:** L4
* **Content:** SELECT 语句没有 WHERE 子句,可能检查比预期更多的行(全表扫描)。对于 SELECT COUNT(\*) 类型的请求如果不要求精度,建议使用 SHOW TABLE STATUS 或 EXPLAIN 替代。
## INSERT INTO xx SELECT 加锁粒度较大请谨慎
* **Item:** LCK.001
* **Severity:** L3
* **Content:** INSERT INTO xx SELECT 加锁粒度较大请谨慎
# Query: 466F1AC2F5851149
★ ★ ★ ★ ★ 100分
```sql
REPLACE INTO city (country_id)
VALUES
(1),
(2),
(3)
```
## OK
# Query: A7973BDD268F926E
★ ★ ★ ★ ☆ 85分
```sql
REPLACE INTO city (country_id)
SELECT
10
FROM
DUAL
```
## INSERT INTO xx SELECT 加锁粒度较大请谨慎
* **Item:** LCK.001
* **Severity:** L3
* **Content:** INSERT INTO xx SELECT 加锁粒度较大请谨慎
# Query: 105C870D5DFB6710
★ ★ ★ ☆ ☆ 65分
```sql
SELECT
film_id
FROM
(
SELECT
film_id
FROM
(
SELECT
film_id
FROM
(
SELECT
film_id
FROM
(
SELECT
film_id
FROM
(
SELECT
film_id
FROM
(
SELECT
film_id
FROM
(
SELECT
film_id
FROM
(
SELECT
film_id
FROM
(
SELECT
film_id
FROM
(
SELECT
film_id
FROM
(
SELECT
film_id
FROM
(
SELECT
film_id
FROM
(
SELECT
film_id
FROM
(
SELECT
film_id
FROM
(
SELECT
film_id
FROM
(
SELECT
film_id
FROM
film
) film
) film
) film
) film
) film
) film
) film
) film
) film
) film
) film
) film
) film
) film
) film
) film
```
## 最外层 SELECT 未指定 WHERE 条件
* **Item:** CLA.001
* **Severity:** L4
* **Content:** SELECT 语句没有 WHERE 子句,可能检查比预期更多的行(全表扫描)。对于 SELECT COUNT(\*) 类型的请求如果不要求精度,建议使用 SHOW TABLE STATUS 或 EXPLAIN 替代。
## 执行计划中嵌套连接深度过深
* **Item:** SUB.004
* **Severity:** L3
* **Content:** MySQL对子查询的优化效果不佳,MySQL将外部查询中的每一行作为依赖子查询执行子查询。 这是导致严重性能问题的常见原因。
# Query: 16C2B14E7DAA9906
★ ☆ ☆ ☆ ☆ 35分
```sql
SELECT
*
FROM
film
WHERE
language_id = (
SELECT
language_id
FROM
language
LIMIT
1)
```
## 最外层 SELECT 未指定 WHERE 条件
* **Item:** CLA.001
* **Severity:** L4
* **Content:** SELECT 语句没有 WHERE 子句,可能检查比预期更多的行(全表扫描)。对于 SELECT COUNT(\*) 类型的请求如果不要求精度,建议使用 SHOW TABLE STATUS 或 EXPLAIN 替代。
## 不建议使用 SELECT * 类型查询
* **Item:** COL.001
* **Severity:** L1
* **Content:** 当表结构变更时,使用 \* 通配符选择所有列将导致查询的含义和行为会发生更改,可能导致查询返回更多的数据。
## 未使用 ORDER BY 的 LIMIT 查询
* **Item:** RES.002
* **Severity:** L4
* **Content:** 没有 ORDER BY 的 LIMIT 会导致非确定性的结果,这取决于查询执行计划。
## MySQL 对子查询的优化效果不佳
* **Item:** SUB.001
* **Severity:** L4
* **Content:** MySQL 将外部查询中的每一行作为依赖子查询执行子查询。 这是导致严重性能问题的常见原因。这可能会在 MySQL 5.6 版本中得到改善, 但对于5.1及更早版本, 建议将该类查询分别重写为 JOIN 或 LEFT OUTER JOIN。
# Query: 16CB4628D2597D40
★ ★ ★ ☆ ☆ 65分
```sql
SELECT
*
FROM
city i
LEFT JOIN country o ON i. city_id= o. country_id
UNION
SELECT
*
FROM
city i
RIGHT JOIN country o ON i. city_id= o. country_id
```
## 建议使用 AS 关键字显示声明一个别名
* **Item:** ALI.001
* **Severity:** L0
* **Content:** 在列或表别名(如"tbl AS alias")中, 明确使用 AS 关键字比隐含别名(如"tbl alias")更易懂。
## 最外层 SELECT 未指定 WHERE 条件
* **Item:** CLA.001
* **Severity:** L4
* **Content:** SELECT 语句没有 WHERE 子句,可能检查比预期更多的行(全表扫描)。对于 SELECT COUNT(\*) 类型的请求如果不要求精度,建议使用 SHOW TABLE STATUS 或 EXPLAIN 替代。
## 不建议使用 SELECT * 类型查询
* **Item:** COL.001
* **Severity:** L1
* **Content:** 当表结构变更时,使用 \* 通配符选择所有列将导致查询的含义和行为会发生更改,可能导致查询返回更多的数据。
## 如果您不在乎重复的话,建议使用 UNION ALL 替代 UNION
* **Item:** SUB.002
* **Severity:** L2
* **Content:** 与去除重复的UNION不同,UNION ALL允许重复元组。如果您不关心重复元组,那么使用UNION ALL将是一个更快的选项。
# Query: EA50643B01E139A8
★ ★ ☆ ☆ ☆ 45分
```sql
SELECT
*
FROM
(
SELECT
*
FROM
actor
WHERE
last_update= '2006-02-15 04:34:33'
AND last_name= 'CHASE'
) t
WHERE
last_update= '2006-02-15 04:34:33'
AND last_name= 'CHASE'
GROUP BY
first_name
```
## 请为 GROUP BY 显示添加 ORDER BY 条件
* **Item:** CLA.008
* **Severity:** L2
* **Content:** 默认 MySQL 会对 'GROUP BY col1, col2, ...' 请求按如下顺序排序 'ORDER BY col1, col2, ...'。如果 GROUP BY 语句不指定 ORDER BY 条件会导致无谓的排序产生,如果不需要排序建议添加 'ORDER BY NULL'。
## 不建议使用 SELECT * 类型查询
* **Item:** COL.001
* **Severity:** L1
* **Content:** 当表结构变更时,使用 \* 通配符选择所有列将导致查询的含义和行为会发生更改,可能导致查询返回更多的数据。
## 非确定性的 GROUP BY
* **Item:** RES.001
* **Severity:** L4
* **Content:** SQL返回的列既不在聚合函数中也不是 GROUP BY 表达式的列中,因此这些值的结果将是非确定性的。如:select a, b, c from tbl where foo="bar" group by a,该 SQL 返回的结果就是不确定的。
## MySQL 对子查询的优化效果不佳
* **Item:** SUB.001
* **Severity:** L4
* **Content:** MySQL 将外部查询中的每一行作为依赖子查询执行子查询。 这是导致严重性能问题的常见原因。这可能会在 MySQL 5.6 版本中得到改善, 但对于5.1及更早版本, 建议将该类查询分别重写为 JOIN 或 LEFT OUTER JOIN。
# Query: 7598A4EDE6CFA6BE
★ ★ ★ ★ ☆ 85分
```sql
SELECT
*
FROM
city i
LEFT JOIN country o ON i. city_id= o. country_id
WHERE
o. country_id is null
UNION
SELECT
*
FROM
city i
RIGHT JOIN country o ON i. city_id= o. country_id
WHERE
i. city_id is null
```
## 建议使用 AS 关键字显示声明一个别名
* **Item:** ALI.001
* **Severity:** L0
* **Content:** 在列或表别名(如"tbl AS alias")中, 明确使用 AS 关键字比隐含别名(如"tbl alias")更易懂。
## 不建议使用 SELECT * 类型查询
* **Item:** COL.001
* **Severity:** L1
* **Content:** 当表结构变更时,使用 \* 通配符选择所有列将导致查询的含义和行为会发生更改,可能导致查询返回更多的数据。
## 如果您不在乎重复的话,建议使用 UNION ALL 替代 UNION
* **Item:** SUB.002
* **Severity:** L2
* **Content:** 与去除重复的UNION不同,UNION ALL允许重复元组。如果您不关心重复元组,那么使用UNION ALL将是一个更快的选项。
# Query: 1E8B70E30062FD13
★ ★ ★ ★ ☆ 80分
```sql
SELECT
first_name, last_name, email
FROM
customer STRAIGHT_JOIN address ON customer. address_id= address. address_id
```
## 最外层 SELECT 未指定 WHERE 条件
* **Item:** CLA.001
* **Severity:** L4
* **Content:** SELECT 语句没有 WHERE 子句,可能检查比预期更多的行(全表扫描)。对于 SELECT COUNT(\*) 类型的请求如果不要求精度,建议使用 SHOW TABLE STATUS 或 EXPLAIN 替代。
# Query: E48A20D0413512DA
★ ☆ ☆ ☆ ☆ 30分
```sql
SELECT
ID, name
FROM
(
SELECT
address
FROM
customer_list
WHERE
SID= 1
ORDER BY
phone
LIMIT
50, 10) a
JOIN customer_list l ON (a. address= l. address)
JOIN city c ON (c. city= l. city)
ORDER BY
phone desc
```
## 建议使用 AS 关键字显示声明一个别名
* **Item:** ALI.001
* **Severity:** L0
* **Content:** 在列或表别名(如"tbl AS alias")中, 明确使用 AS 关键字比隐含别名(如"tbl alias")更易懂。
## 最外层 SELECT 未指定 WHERE 条件
* **Item:** CLA.001
* **Severity:** L4
* **Content:** SELECT 语句没有 WHERE 子句,可能检查比预期更多的行(全表扫描)。对于 SELECT COUNT(\*) 类型的请求如果不要求精度,建议使用 SHOW TABLE STATUS 或 EXPLAIN 替代。
## ORDER BY 语句对多个不同条件使用不同方向的排序无法使用索引
* **Item:** CLA.007
* **Severity:** L2
* **Content:** ORDER BY 子句中的所有表达式必须按统一的 ASC 或 DESC 方向排序,以便利用索引。
## 同一张表被连接两次
* **Item:** JOI.002
* **Severity:** L4
* **Content:** 相同的表在 FROM 子句中至少出现两次,可以简化为对该表的单次访问。
## MySQL 对子查询的优化效果不佳
* **Item:** SUB.001
* **Severity:** L4
* **Content:** MySQL 将外部查询中的每一行作为依赖子查询执行子查询。 这是导致严重性能问题的常见原因。这可能会在 MySQL 5.6 版本中得到改善, 但对于5.1及更早版本, 建议将该类查询分别重写为 JOIN 或 LEFT OUTER JOIN。
# Query: B0BA5A7079EA16B3
★ ★ ★ ★ ☆ 85分
```sql
SELECT
*
FROM
film
WHERE
DATE( last_update) = '2006-02-15'
```
## 不建议使用 SELECT * 类型查询
* **Item:** COL.001
* **Severity:** L1
* **Content:** 当表结构变更时,使用 \* 通配符选择所有列将导致查询的含义和行为会发生更改,可能导致查询返回更多的数据。
## 避免在 WHERE 条件中使用函数或其他运算符
* **Item:** FUN.001
* **Severity:** L2
* **Content:** 虽然在 SQL 中使用函数可以简化很多复杂的查询,但使用了函数的查询无法利用表中已经建立的索引,该查询将会是全表扫描,性能较差。通常建议将列名写在比较运算符左侧,将查询过滤条件放在比较运算符右侧。也不建议在查询比较条件两侧书写多余的括号,这会对阅读产生比较大的困扰。
# Query: 18A2AD1395A58EAE
★ ★ ★ ☆ ☆ 60分
```sql
SELECT
last_update
FROM
film
GROUP BY
DATE( last_update)
```
## 最外层 SELECT 未指定 WHERE 条件
* **Item:** CLA.001
* **Severity:** L4
* **Content:** SELECT 语句没有 WHERE 子句,可能检查比预期更多的行(全表扫描)。对于 SELECT COUNT(\*) 类型的请求如果不要求精度,建议使用 SHOW TABLE STATUS 或 EXPLAIN 替代。
## 请为 GROUP BY 显示添加 ORDER BY 条件
* **Item:** CLA.008
* **Severity:** L2
* **Content:** 默认 MySQL 会对 'GROUP BY col1, col2, ...' 请求按如下顺序排序 'ORDER BY col1, col2, ...'。如果 GROUP BY 语句不指定 ORDER BY 条件会导致无谓的排序产生,如果不需要排序建议添加 'ORDER BY NULL'。
## GROUP BY 的条件为表达式
* **Item:** CLA.010
* **Severity:** L2
* **Content:** 当 GROUP BY 条件为表达式或函数时会使用到临时表,如果在未指定 WHERE 或 WHERE 条件返回的结果集较大时性能会很差。
# Query: 60F234BA33AAC132
★ ★ ★ ☆ ☆ 70分
```sql
SELECT
last_update
FROM
film
ORDER BY
DATE( last_update)
```
## 最外层 SELECT 未指定 WHERE 条件
* **Item:** CLA.001
* **Severity:** L4
* **Content:** SELECT 语句没有 WHERE 子句,可能检查比预期更多的行(全表扫描)。对于 SELECT COUNT(\*) 类型的请求如果不要求精度,建议使用 SHOW TABLE STATUS 或 EXPLAIN 替代。
## ORDER BY 的条件为表达式
* **Item:** CLA.009
* **Severity:** L2
* **Content:** 当 ORDER BY 条件为表达式或函数时会使用到临时表,如果在未指定 WHERE 或 WHERE 条件返回的结果集较大时性能会很差。
# Query: 1ED2B7ECBA4215E1
★ ★ ★ ★ ☆ 90分
```sql
SELECT
description
FROM
film
WHERE
description IN( 'NEWS',
'asd'
)
GROUP BY
description
```
## 请为 GROUP BY 显示添加 ORDER BY 条件
* **Item:** CLA.008
* **Severity:** L2
* **Content:** 默认 MySQL 会对 'GROUP BY col1, col2, ...' 请求按如下顺序排序 'ORDER BY col1, col2, ...'。如果 GROUP BY 语句不指定 ORDER BY 条件会导致无谓的排序产生,如果不需要排序建议添加 'ORDER BY NULL'。
# Query: 255BAC03F56CDBC7
★ ★ ★ ★ ★ 100分
```sql
ALTER TABLE
address
ADD
index idx_city_id( city_id)
```
## OK
# Query: C315BC4EE0F4E523
★ ★ ★ ★ ★ 100分
```sql
ALTER TABLE
inventory
ADD
index `idx_store_film` (
`store_id`, `film_id`)
```
## 提醒:请将索引属性顺序与查询对齐
* **Item:** KEY.004
* **Severity:** L0
* **Content:** 如果为列创建复合索引,请确保查询属性与索引属性的顺序相同,以便DBMS在处理查询时使用索引。如果查询和索引属性订单没有对齐,那么DBMS可能无法在查询处理期间使用索引。
# Query: 9BB74D074BA0727C
★ ★ ★ ★ ★ 100分
```sql
ALTER TABLE
inventory
ADD
index `idx_store_film` (
`store_id`, `film_id`),
ADD
index `idx_store_film` (
`store_id`, `film_id`),
ADD
index `idx_store_film` (
`store_id`, `film_id`)
```
## 提醒:请将索引属性顺序与查询对齐
* **Item:** KEY.004
* **Severity:** L0
* **Content:** 如果为列创建复合索引,请确保查询属性与索引属性的顺序相同,以便DBMS在处理查询时使用索引。如果查询和索引属性订单没有对齐,那么DBMS可能无法在查询处理期间使用索引。
# Query: C95B5C028C8FFF95
★ ★ ☆ ☆ ☆ 40分
```sql
SELECT
DATE_FORMAT( t. last_update, '%Y-%m-%d'
),
COUNT( DISTINCT (
t. city))
FROM
city t
WHERE
t. last_update > '2018-10-22 00:00:00'
AND t. city LIKE '%Chrome%'
AND t. city = 'eip'
GROUP BY
DATE_FORMAT( t. last_update, '%Y-%m-%d'
)
ORDER BY
DATE_FORMAT( t. last_update, '%Y-%m-%d'
)
```
## 建议使用 AS 关键字显示声明一个别名
* **Item:** ALI.001
* **Severity:** L0
* **Content:** 在列或表别名(如"tbl AS alias")中, 明确使用 AS 关键字比隐含别名(如"tbl alias")更易懂。
## 不建议使用前项通配符查找
* **Item:** ARG.001
* **Severity:** L4
* **Content:** 例如 "%foo",查询参数有一个前项通配符的情况无法使用已有索引。
## ORDER BY 的条件为表达式
* **Item:** CLA.009
* **Severity:** L2
* **Content:** 当 ORDER BY 条件为表达式或函数时会使用到临时表,如果在未指定 WHERE 或 WHERE 条件返回的结果集较大时性能会很差。
## GROUP BY 的条件为表达式
* **Item:** CLA.010
* **Severity:** L2
* **Content:** 当 GROUP BY 条件为表达式或函数时会使用到临时表,如果在未指定 WHERE 或 WHERE 条件返回的结果集较大时性能会很差。
## ORDER BY 多个列但排序方向不同时可能无法使用索引
* **Item:** KEY.008
* **Severity:** L4
* **Content:** 在 MySQL 8.0之前当 ORDER BY 多个列指定的排序方向不同时将无法使用已经建立的索引。
# Query: C11ECE7AE5F80CE5
★ ★ ☆ ☆ ☆ 45分
```sql
create table hello. t (id int unsigned)
```
## 建议为表添加注释
* **Item:** CLA.011
* **Severity:** L1
* **Content:** 为表添加注释能够使得表的意义更明确,从而为日后的维护带来极大的便利。
## 请为列添加默认值
* **Item:** COL.004
* **Severity:** L1
* **Content:** 请为列添加默认值,如果是 ALTER 操作,请不要忘记将原字段的默认值写上。字段无默认值,当表较大时无法在线变更表结构。
## 列未添加注释
* **Item:** COL.005
* **Severity:** L1
* **Content:** 建议对表中每个列添加注释,来明确每个列在表中的含义及作用。
## 未指定主键或主键非 int 或 bigint
* **Item:** KEY.007
* **Severity:** L4
* **Content:** 未指定主键或主键非 int 或 bigint,建议将主键设置为 int unsigned 或 bigint unsigned。
## 请为表选择合适的存储引擎
* **Item:** TBL.002
* **Severity:** L4
* **Content:** 建表或修改表的存储引擎时建议使用推荐的存储引擎,如:innodb
# Query: 291F95B7DCB74C21
★ ★ ★ ★ ☆ 95分
```sql
SELECT
*
FROM
tb
WHERE
data >= ''
```
## 不建议使用 SELECT * 类型查询
* **Item:** COL.001
* **Severity:** L1
* **Content:** 当表结构变更时,使用 \* 通配符选择所有列将导致查询的含义和行为会发生更改,可能导致查询返回更多的数据。
# Query: 084DA3E3EE38DD85
★ ★ ★ ★ ★ 100分
```sql
ALTER TABLE
tb alter column id
DROP
DEFAULT
```
## OK
online-dsn:
user: online-test
password: '********'
net: tcp
addr: 192.168.12.200:3307
schema: information_schema
charset: utf8mb4
collation: utf8mb4_general_ci
loc: GMT
tls: dsfsfdsf
server-public-key: AAAAB3NzaC1yc2EAAAADAQABAAABAQC0JFhoEgrl5/51UHlIIlfWwhiJLR/EEeF8enGnY0PnAldLQ8STdWD8Um2BUtVjgE9COl1X3mN4vMvnSm8A6aPn66enHn0hKzwh1GvcuZNTPgeaZyGKWG0kcvbziUjAPsxxvRvvoaUspSkRYAP/9vpq3SImJKuIHCPfjnGMurKV1n7W/QfpmNjUEwYOswDjL1Ik6Jy6Lrzf8T0hQEy+dYoV4zNM0HcROCXFuu1LyG+WTch3FW660BecNT8+c4sVTHuUMXgGot8OUtwgfXrt5ZL5as7cuyKiWsLVrtrtvL3T0ZHlV8qxQ3DT1gqjSw6jBOzyDOx3jwthAbdsWjyK4Oqp
maxallowedpacket: 419437
params:
charset: utf8mb4
timeout: 60
read-timeout: 70
write-timeout: 80
allow-native-passwords: false
allow-old-passwords: true
disable: false
test-dsn:
user: test-user
password: '********'
net: tcp
addr: 192.168.12.34:3309
schema: information_schema
charset: utf8mb4
collation: utf8mb4_general_ci
loc: GMT
tls: aabbbaa
server-public-key: this is a tset serverpublic
maxallowedpacket: 4194309
params:
charset: utf8mb4
timeout: 50
read-timeout: 40
write-timeout: 30
allow-native-passwords: false
allow-old-passwords: true
disable: false
allow-online-as-test: true
drop-test-temporary: false
cleanup-test-database: true
only-syntax-check: true
sampling-statistic-target: 110
sampling: true
sampling-condition: aaa
profiling: true
trace: true
explain: false
delimiter: ;
log-level: 5
log-output: /dev/null
report-type: html
report-css: sdfs
report-javascript: sdfsd
report-title: SQL优化分析报告-test
markdown-extensions: 92
markdown-html-flags: 10
ignore-rules:
- COL.012
rewrite-rules:
- delimiter
- orderbynull
- groupbyconst
- dmlorderby
- having
- star2columns
- insertcolumns
- distinctstar
blacklist: /tmp/blacklist
max-join-table-count: 12
max-group-by-cols-count: 15
max-distinct-count: 7
max-index-cols-count: 2
max-text-cols-count: 3
max-total-rows: 9999991
max-query-cost: 9992
spaghetti-query-length: 2041
allow-drop-index: true
max-in-count: 101
max-index-bytes-percolumn: 762
max-index-bytes: 3073
allow-charsets:
- utf8
- utf8mb4
allow-collates: []
allow-engines:
- innodb
- tokudb
max-index-count: 12
max-column-count: 41
max-value-count: 102
index-prefix: idx_
unique-key-prefix: uk_
max-subquery-depth: 6
max-varchar-length: 1022
column-not-allow-type:
- boolean
min-cardinality: 2
explain-sql-report-type: pretty
explain-type: extended
explain-format: traditional
explain-warn-select-type:
- ""
explain-warn-access-type:
- ALL
explain-max-keys: 31
explain-min-keys: 10
explain-max-rows: 10002
explain-warn-extra:
- Using temporary
- Using filesort
explain-max-filtered: 120
explain-warn-scalability:
- O(log(n))
show-warnings: true
show-last-query-cost: true
query: ""
list-heuristic-rules: true
list-rewrite-rules: true
list-test-sqls: true
list-report-types: true
verbose: true
dry-run: false
max-pretty-sql-length: 1022
...@@ -35,31 +35,21 @@ load test_helper ...@@ -35,31 +35,21 @@ load test_helper
} }
# 6. soar 使用配置文件修改默认参数是否正确 # 6. soar 使用配置文件修改默认参数是否正确
# 注意 不启用的配置为默认配置项目 # 注意不启用的配置为默认配置项目
@test "Check the default config of the changes" { @test "Check the default config of the changes" {
${SOAR_BIN} -config ${BATS_FIXTURE_DIRNAME}/${BATS_TEST_NAME}.golden -print-config -log-output=/dev/null > ${BATS_TMP_DIRNAME}/${BATS_TEST_NAME}.golden ${SOAR_BIN} -config ${BATS_FIXTURE_DIRNAME}/${BATS_TEST_NAME}.yaml -print-config -log-output=/dev/null > ${BATS_TMP_DIRNAME}/${BATS_TEST_NAME}.golden
# 去掉 2019/01/12 05:45:14.922 [D] [config.go:429] go-sql-driver/mysql.ParseDSN Error: invalid value / unknown server pub
sed -n '3,$p' ${BATS_TMP_DIRNAME}/${BATS_TEST_NAME}.golden > ${BATS_TMP_DIRNAME}/${BATS_TEST_NAME}.golden1
mv ${BATS_TMP_DIRNAME}/${BATS_TEST_NAME}.golden1 ${BATS_TMP_DIRNAME}/${BATS_TEST_NAME}.golden
run golden_diff run golden_diff
[ $status -eq 0 ] [ $status -eq 0 ]
} }
# 8. 执行 soar -query 为string时是否正常 # 8. 执行 soar -query 为文件时是否正常
@test "Check soar query for input string" {
${SOAR_BIN} -query "`${SOAR_BIN} -list-test-sqls`" > ${BATS_TMP_DIRNAME}/${BATS_TEST_NAME}.golden
run golden_diff
[ $status -eq 0 ]
}
# 8. 执行 soar -query 为文件时是否正常
@test "Check soar query for input file" { @test "Check soar query for input file" {
${SOAR_BIN} -query <(${SOAR_BIN} -list-test-sqls) > ${BATS_TMP_DIRNAME}/${BATS_TEST_NAME}.golden ${SOAR_BIN} -query <(${SOAR_BIN} -list-test-sqls) > ${BATS_TMP_DIRNAME}/${BATS_TEST_NAME}.golden
run golden_diff run golden_diff
[ $status -eq 0 ] [ $status -eq 0 ]
} }
# 9. 管道输入 sql 是否正常 # 9. 管道输入 SQL 是否正常
@test "Check soar for pipe input" { @test "Check soar for pipe input" {
${SOAR_BIN} -list-test-sqls |${SOAR_BIN} > ${BATS_TMP_DIRNAME}/${BATS_TEST_NAME}.golden ${SOAR_BIN} -list-test-sqls |${SOAR_BIN} > ${BATS_TMP_DIRNAME}/${BATS_TEST_NAME}.golden
run golden_diff run golden_diff
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册