diff --git a/test/fixture/test_Check_soar_for_pipe_input.golden b/test/fixture/test_Check_soar_for_pipe_input.golden new file mode 100644 index 0000000000000000000000000000000000000000..9a7698b777ca848bdab9c1e2b951843f99229dd7 --- /dev/null +++ b/test/fixture/test_Check_soar_for_pipe_input.golden @@ -0,0 +1,2505 @@ +# 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 + diff --git a/test/fixture/test_Check_soar_query_for_input_file.golden b/test/fixture/test_Check_soar_query_for_input_file.golden new file mode 100644 index 0000000000000000000000000000000000000000..9a7698b777ca848bdab9c1e2b951843f99229dd7 --- /dev/null +++ b/test/fixture/test_Check_soar_query_for_input_file.golden @@ -0,0 +1,2505 @@ +# 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 + diff --git a/test/fixture/test_Check_soar_query_for_input_string.golden b/test/fixture/test_Check_soar_query_for_input_string.golden new file mode 100644 index 0000000000000000000000000000000000000000..9a7698b777ca848bdab9c1e2b951843f99229dd7 --- /dev/null +++ b/test/fixture/test_Check_soar_query_for_input_string.golden @@ -0,0 +1,2505 @@ +# 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 + diff --git a/test/fixture/test_Check_the_default_config_of_the_changes.golden b/test/fixture/test_Check_the_default_config_of_the_changes.golden new file mode 100644 index 0000000000000000000000000000000000000000..8b7a9a20ca3a76dc221ff32f349156c091fae8b6 --- /dev/null +++ b/test/fixture/test_Check_the_default_config_of_the_changes.golden @@ -0,0 +1,126 @@ +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 diff --git a/test/main.bats b/test/main.bats index 38fbfd2e167f73204d83ec68dc8156090e427a0e..b989d742c97085c2fdc2ec002288c2cc4acc11c1 100644 --- a/test/main.bats +++ b/test/main.bats @@ -2,39 +2,77 @@ load test_helper +# 1. 检查版本输出格式是否正确 +# 2. 检查版本是否为当天编译的 @test "Test soar version" { run ${SOAR_BIN} -version [ "$status" -eq 0 ] [ "${lines[0]%% *}" == "Version:" ] [ "${lines[1]%% *}" == "Branch:" ] [ "${lines[2]%% *}" == "Compile:" ] - [ $(expr "${lines[2]}" : "Compile: $(date +'%Y-%m-%d').*") -ne 0 ] + [ $(expr "${lines[2]}" : "Compile: $(date +'%Y-%m-%d').*") -ne 0 ] # 检查当前版本是否为今日编译的 } +# 3. 无参数执行是否正确 @test "No arguments prints message" { run ${SOAR_BIN} [ $status -eq 1 ] [ "${lines[0]}" == 'Args format error, use --help see how to use it!' ] } +# 4. 检查输出的默认值是否改变 soar -print-config 加log-outpt 是因为日志默认是相对路径 @test "Run default printconfig cases" { ${SOAR_BIN} -print-config -log-output=/dev/null > ${BATS_TMP_DIRNAME}/${BATS_TEST_NAME}.golden run golden_diff [ $status -eq 0 ] } +# 5. soar 使用 config 配置文件路径是否正确 @test "Check config cases" { run ${SOAR_BIN_ENV} -check-config [ $status -eq 0 ] [ -z ${output} ] } +# 6. soar 使用配置文件修改默认参数是否正确 +# 注意 不启用的配置为默认配置项目 +@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 + # 去掉 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 + [ $status -eq 0 ] +} + +# 8. 执行 soar -query 为string时是否正常 +@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" { + ${SOAR_BIN} -query <(${SOAR_BIN} -list-test-sqls) > ${BATS_TMP_DIRNAME}/${BATS_TEST_NAME}.golden + run golden_diff + [ $status -eq 0 ] +} + +# 9. 管道输入 sql 是否正常 +@test "Check soar for pipe input" { + ${SOAR_BIN} -list-test-sqls |${SOAR_BIN} > ${BATS_TMP_DIRNAME}/${BATS_TEST_NAME}.golden + run golden_diff + [ $status -eq 0 ] +} + +# 17. 语法检查(正确) @test "Syntax Check OK" { run ${SOAR_BIN} -query "select * from film" -only-syntax-check [ $status -eq 0 ] [ -z $ouput ] } - +# 17. 语法检查(错误) @test "Syntax Check Error" { run ${SOAR_BIN} -query "select * frm film" -only-syntax-check [ $status -eq 1 ]