# 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

★ ★ ★ ★ ☆ 85分

```sql

SELECT  
  * 
FROM  
  film  
WHERE  
  LENGTH  = 114  
  AND  title  = 'ALABAMA DEVIL'
```

##  不建议使用 SELECT * 类型查询

* **Item:**  COL.001

* **Severity:**  L1

* **Content:**  当表结构变更时，使用 \* 通配符选择所有列将导致查询的含义和行为会发生更改，可能导致查询返回更多的数据。

##  不建议使用连续判断

* **Item:**  RES.009

* **Severity:**  L2

* **Content:**  类似这样的 SELECT \* FROM tbl WHERE col = col = 'abc' 语句可能是书写错误，您可能想表达的含义是 col = 'abc'。如果确实是业务需求建议修改为 col = col and col = 'abc'。

# Query: 68E48001ECD53152

★ ★ ★ ★ ☆ 85分

```sql

SELECT  
  * 
FROM  
  film  
WHERE  
  LENGTH  > 100  
  AND  title  = 'ALABAMA DEVIL'
```

##  不建议使用 SELECT * 类型查询

* **Item:**  COL.001

* **Severity:**  L1

* **Content:**  当表结构变更时，使用 \* 通配符选择所有列将导致查询的含义和行为会发生更改，可能导致查询返回更多的数据。

##  不建议使用连续判断

* **Item:**  RES.009

* **Severity:**  L2

* **Content:**  类似这样的 SELECT \* FROM tbl WHERE col = col = 'abc' 语句可能是书写错误，您可能想表达的含义是 col = 'abc'。如果确实是业务需求建议修改为 col = col and col = 'abc'。

# Query: 12FF1DAA3D425FA9

★ ★ ★ ★ ☆ 85分

```sql

SELECT  
  * 
FROM  
  film  
WHERE  
  LENGTH  > 100  
  AND  language_id  < 10  
  AND  title  = 'xyz'
```

##  不建议使用 SELECT * 类型查询

* **Item:**  COL.001

* **Severity:**  L1

* **Content:**  当表结构变更时，使用 \* 通配符选择所有列将导致查询的含义和行为会发生更改，可能导致查询返回更多的数据。

##  不建议使用连续判断

* **Item:**  RES.009

* **Severity:**  L2

* **Content:**  类似这样的 SELECT \* FROM tbl WHERE col = col = 'abc' 语句可能是书写错误，您可能想表达的含义是 col = 'abc'。如果确实是业务需求建议修改为 col = col and col = 'abc'。

# Query: E84CBAAC2E12BDEA

★ ★ ★ ★ ☆ 85分

```sql

SELECT  
  * 
FROM  
  film  
WHERE  
  LENGTH  > 100  
  AND  language_id  < 10
```

##  不建议使用 SELECT * 类型查询

* **Item:**  COL.001

* **Severity:**  L1

* **Content:**  当表结构变更时，使用 \* 通配符选择所有列将导致查询的含义和行为会发生更改，可能导致查询返回更多的数据。

##  不建议使用连续判断

* **Item:**  RES.009

* **Severity:**  L2

* **Content:**  类似这样的 SELECT \* FROM tbl WHERE col = col = 'abc' 语句可能是书写错误，您可能想表达的含义是 col = 'abc'。如果确实是业务需求建议修改为 col = col and col = 'abc'。

# Query: 6A0F035BD4E01018

★ ★ ★ ☆ ☆ 75分

```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

##  不建议使用连续判断

* **Item:**  RES.009

* **Severity:**  L2

* **Content:**  类似这样的 SELECT \* FROM tbl WHERE col = col = 'abc' 语句可能是书写错误，您可能想表达的含义是 col = 'abc'。如果确实是业务需求建议修改为 col = col and col = 'abc'。

# 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

★ ★ ★ ★ ☆ 85分

```sql

SELECT  
  * 
FROM  
  film  
WHERE  
  release_year  = 2016  
  AND  LENGTH  != 1  
ORDER BY  
  title
```

##  不建议使用 SELECT * 类型查询

* **Item:**  COL.001

* **Severity:**  L1

* **Content:**  当表结构变更时，使用 \* 通配符选择所有列将导致查询的含义和行为会发生更改，可能导致查询返回更多的数据。

##  不建议使用连续判断

* **Item:**  RES.009

* **Severity:**  L2

* **Content:**  类似这样的 SELECT \* FROM tbl WHERE col = col = 'abc' 语句可能是书写错误，您可能想表达的含义是 col = 'abc'。如果确实是业务需求建议修改为 col = col and col = 'abc'。

##  '!=' 运算符是非标准的

* **Item:**  STA.001

* **Severity:**  L0

* **Content:**  "<>"才是标准SQL中的不等于运算符。

# Query: 4E73AA068370E6A8

★ ★ ★ ★ ★ 100分

```sql

SELECT  
  title  
FROM  
  film  
WHERE  
  release_year  = 1995
```

##  OK

# Query: BA7111449E4F1122

★ ★ ★ ★ ☆ 90分

```sql

SELECT  
  title, replacement_cost  
FROM  
  film  
WHERE  
  language_id  = 5  
  AND  LENGTH  = 70
```

##  不建议使用连续判断

* **Item:**  RES.009

* **Severity:**  L2

* **Content:**  类似这样的 SELECT \* FROM tbl WHERE col = col = 'abc' 语句可能是书写错误，您可能想表达的含义是 col = 'abc'。如果确实是业务需求建议修改为 col = col and col = 'abc'。

# Query: B13E0ACEAF8F3119

★ ★ ★ ★ ☆ 90分

```sql

SELECT  
  title  
FROM  
  film  
WHERE  
  language_id  > 5  
  AND  LENGTH  > 70
```

##  不建议使用连续判断

* **Item:**  RES.009

* **Severity:**  L2

* **Content:**  类似这样的 SELECT \* FROM tbl WHERE col = col = 'abc' 语句可能是书写错误，您可能想表达的含义是 col = 'abc'。如果确实是业务需求建议修改为 col = col and col = 'abc'。

# Query: A3FAB6027484B88B

★ ★ ★ ★ ☆ 85分

```sql

SELECT  
  * 
FROM  
  film  
WHERE  
  LENGTH  = 100  
  AND  title  = 'xyz' 
ORDER BY  
  release_year
```

##  不建议使用 SELECT * 类型查询

* **Item:**  COL.001

* **Severity:**  L1

* **Content:**  当表结构变更时，使用 \* 通配符选择所有列将导致查询的含义和行为会发生更改，可能导致查询返回更多的数据。

##  不建议使用连续判断

* **Item:**  RES.009

* **Severity:**  L2

* **Content:**  类似这样的 SELECT \* FROM tbl WHERE col = col = 'abc' 语句可能是书写错误，您可能想表达的含义是 col = 'abc'。如果确实是业务需求建议修改为 col = col and col = 'abc'。

# Query: CB42080E9F35AB07

★ ★ ★ ★ ☆ 85分

```sql

SELECT  
  * 
FROM  
  film  
WHERE  
  LENGTH  > 100  
  AND  title  = 'xyz' 
ORDER BY  
  release_year
```

##  不建议使用 SELECT * 类型查询

* **Item:**  COL.001

* **Severity:**  L1

* **Content:**  当表结构变更时，使用 \* 通配符选择所有列将导致查询的含义和行为会发生更改，可能导致查询返回更多的数据。

##  不建议使用连续判断

* **Item:**  RES.009

* **Severity:**  L2

* **Content:**  类似这样的 SELECT \* FROM tbl WHERE col = col = 'abc' 语句可能是书写错误，您可能想表达的含义是 col = 'abc'。如果确实是业务需求建议修改为 col = col and col = 'abc'。

# 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: F76BFFC87914E3D5

★ ★ ★ ☆ ☆ 60分

```sql

SELECT  
  d. deptno, d. dname, d. loc  
FROM  
  scott. dept  d  
WHERE  
  d. deptno  IN  (
SELECT  
  e. deptno  
FROM  
  scott. emp  e)
```

##  建议使用 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: 7253A3D336F9F3FE

★ ☆ ☆ ☆ ☆ 30分

```sql

SELECT  
  visitor_id, url  
FROM  
  (
SELECT  
  id  
FROM  
  LOG  
WHERE  
  ip= "123.45.67.89" 
ORDER BY  
  ts  desc  
LIMIT  
  50, 10) I  
  JOIN  LOG  ON  (I. id= LOG. id) 
  JOIN  url  ON  (url. id= LOG. url_id) 
ORDER BY  
  TS  desc
```

##  最外层 SELECT 未指定 WHERE 条件

* **Item:**  CLA.001

* **Severity:**  L4

* **Content:**  SELECT 语句没有 WHERE 子句，可能检查比预期更多的行(全表扫描)。对于 SELECT COUNT(\*) 类型的请求如果不要求精度，建议使用 SHOW TABLE STATUS 或 EXPLAIN 替代。

##  同一张表被连接两次

* **Item:**  JOI.002

* **Severity:**  L4

* **Content:**  相同的表在 FROM 子句中至少出现两次，可以简化为对该表的单次访问。

##  用字符类型存储IP地址

* **Item:**  LIT.001

* **Severity:**  L2

* **Content:**  字符串字面上看起来像IP地址，但不是 INET\_ATON() 的参数，表示数据被存储为字符而不是整数。将IP地址存储为整数更为有效。

##  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

★ ★ ★ ★ ☆ 90分

```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
```

##  不建议使用连续判断

* **Item:**  RES.009

* **Severity:**  L2

* **Content:**  类似这样的 SELECT \* FROM tbl WHERE col = col = 'abc' 语句可能是书写错误，您可能想表达的含义是 col = 'abc'。如果确实是业务需求建议修改为 col = col and col = 'abc'。

# 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

★ ☆ ☆ ☆ ☆ 35分

```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 返回的结果就是不确定的。

##  不建议使用连续判断

* **Item:**  RES.009

* **Severity:**  L2

* **Content:**  类似这样的 SELECT \* FROM tbl WHERE col = col = 'abc' 语句可能是书写错误，您可能想表达的含义是 col = 'abc'。如果确实是业务需求建议修改为 col = col and col = 'abc'。

##  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: CE8A69541550D286

★ ☆ ☆ ☆ ☆ 30分

```sql

SELECT  
  DATE_FORMAT( t. atm, '%Y-%m-%d'
), 
COUNT( DISTINCT  (
  t. usr)) 
  FROM  
    usr_terminal  t  
  WHERE  
    t. atm  > '2018-10-22 00:00:00' 
    AND  t. agent  LIKE  '%Chrome%' 
    AND  t. system  = 'eip' 
  GROUP BY  
    DATE_FORMAT( t. atm, '%Y-%m-%d'
) 
ORDER BY  
  DATE_FORMAT( t. atm, '%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 多个列指定的排序方向不同时将无法使用已经建立的索引。

##  不建议使用连续判断

* **Item:**  RES.009

* **Severity:**  L2

* **Content:**  类似这样的 SELECT \* FROM tbl WHERE col = col = 'abc' 语句可能是书写错误，您可能想表达的含义是 col = 'abc'。如果确实是业务需求建议修改为 col = col and col = 'abc'。

# 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

