Skip to content
Merged
35 changes: 19 additions & 16 deletions faq/sql-faq.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,11 @@ aliases: ['/docs-cn/dev/faq/sql-faq/']

详细可参考[系统变量](/system-variables.md)。

## TiDB 是否支持 select for update
## TiDB 是否支持 `SELECT FOR UPDATE`

支持,但语义上和 MySQL 有区别,TiDB 是分布式数据库,3.0.8 版本前,采用的乐观锁机制,也就说 select for update 不在事务开启就锁住数据,而是其他事务在提交的时候进行冲突检查,如有冲突,会进行回滚。3.0.8 版本之后,默认采用悲观锁机制,行为和 MySQL 基本一致,SELECT FOR UPDATE 会读取已提交的最新数据,并对读取到的数据加悲观锁。
支持。当 TiDB 使用悲观锁(自 TiDB v3.0 起默认使用)时,TiDB 中 `SELECT FOR UPDATE` 的行为与 MySQL 中的基本一致。

当 TiDB 使用乐观锁时,`SELECT FOR UPDATE` 不会在事务启动时对数据加锁,而是在提交事务时检查冲突。如果检查出冲突,会回滚待提交的事务。

## TiDB 的 codec 能保证 UTF8 的字符串是 memcomparable 的吗?我们的 key 需要支持 UTF8,有什么编码建议吗?

Expand All @@ -26,11 +28,11 @@ TiDB 字符集默认就是 UTF8 而且目前只支持 UTF8,字符串就是 mem

## TiDB 中,为什么出现后插入数据的自增 ID 反而小?

TiDB 的自增 ID (`AUTO_INCREMENT`) 只保证自增且唯一,并不保证连续分配。TiDB 目前采用批量分配的方式,所以如果在多台 TiDB 上同时插入数据,分配的自增 ID 会不连续。当多个线程并发往不同的 tidb-server 插入数据的时候,有可能会出现后插入的数据自增 ID 小的情况。此外,TiDB允许给整型类型的字段指定 AUTO_INCREMENT,且一个表只允许一个属性为 `AUTO_INCREMENT` 的字段。详情可参考[CREATE TABLE 语法](/mysql-compatibility.md#自增-id)。
TiDB 的自增 ID (`AUTO_INCREMENT`) 只保证自增且唯一,并不保证连续分配。TiDB 目前采用批量分配的方式,所以如果在多台 TiDB 上同时插入数据,分配的自增 ID 会不连续。当多个线程并发往不同的 TiDB-server 插入数据的时候,有可能会出现后插入的数据自增 ID 小的情况。此外,TiDB 允许给整型类型的字段指定 AUTO_INCREMENT,且一个表只允许一个属性为 `AUTO_INCREMENT` 的字段。详情可参考 [CREATE TABLE 语法](/mysql-compatibility.md#自增-id)。

## sql_mode 默认除了通过命令 set 修改,配置文件怎么修改
## 如何在 TiDB 中修改 `sql_mode`

TiDB sql_mode 与 MySQL 的 sql_mode 设置方法有一些差别,TiDB 不支持配置文件配置设置数据库的 sql\_mode,而只能使用 set 命令去设置,具体方法为:`set @@global.sql_mode = 'STRICT_TRANS_TABLES';`
TiDB 支持将 [`sql_mode`](/sql-mode.md) 作为[系统变量](/system-variables.md#sql_mode)修改,与 MySQL 一致。目前,TiDB 不支持在配置文件中修改 `sql_mode`,但使用 [`SET GLOBAL`](/sql-statements/sql-statement-set-variable.md) 对系统变量的修改将应用于集群中的所有 TiDB server,并且重启后更改依然有效

## 用 Sqoop 批量写入 TiDB 数据,虽然配置了 `--batch` 选项,但还是会遇到 `java.sql.BatchUpdateExecption:statement count 5001 exceeds the transaction limitation` 的错误,该如何解决?

Expand All @@ -49,7 +51,7 @@ TiDB 的 sql_mode 与 MySQL 的 sql_mode 设置方法有一些差别,TiDB 不
--batch
```

- 也可以选择增大 tidb 的单个事物语句数量限制,不过这个会导致内存上涨
- 也可以选择增大 TiDB 的单个事物语句数量限制,不过此操作会导致内存增加

## TiDB 有像 Oracle 那样的 Flashback Query 功能么,DDL 支持么?

Expand All @@ -59,21 +61,21 @@ TiDB 的 sql_mode 与 MySQL 的 sql_mode 设置方法有一些差别,TiDB 不

DELETE,TRUNCATE 和 DROP 都不会立即释放空间。对于 TRUNCATE 和 DROP 操作,在达到 TiDB 的 GC (garbage collection) 时间后(默认 10 分钟),TiDB 的 GC 机制会删除数据并释放空间。对于 DELETE 操作 TiDB 的 GC 机制会删除数据,但不会释放空间,而是当后续数据写入 RocksDB 且进行 compact 时对空间重新利用。

## TiDB 是否支持 replace into 语法?
## TiDB 是否支持 `REPLACE INTO` 语法?

支持,但是 load data 不支持 replace into 语法。
支持,例外是当前 `LOAD DATA` 不支持 `REPLACE INTO` 语法。

## 数据删除后查询速度为何会变慢?

大量删除数据后,会有很多无用的 key 存在,影响查询效率。可以尝试开启 [Region Merge](/best-practices/massive-regions-best-practices.md#方法五开启-region-merge) 功能,具体看参考[最佳实践](https://pingcap.com/blog-cn/tidb-best-practice/)中的删除数据部分。

## 对数据做删除操作之后,空间回收比较慢,如何处理?

可以设置并行 GC,加快对空间的回收速度。默认并发为 1,最大可调整为 tikv 实例数量的 50%。可使用 `update mysql.tidb set VARIABLE_VALUE="3" where VARIABLE_NAME="tikv_gc_concurrency";` 命令来调整。
可以设置并行 GC,加快对空间的回收速度。默认并发为 1,最大可调整为 TiKV 实例数量的 50%。可使用 `update mysql.tidb set VARIABLE_VALUE="3" where VARIABLE_NAME="tikv_gc_concurrency";` 命令来调整。

## show processlist 是否显示系统进程号?
## `SHOW PROCESSLIST` 是否显示系统进程号?

TiDB 的 `show processlist` 与 MySQL 的 `show processlist` 显示内容基本一样,不会显示系统进程号,而 ID 表示当前的 session ID。其中 TiDB 的 `show processlist` 和 MySQL 的 `show processlist` 区别如下:
TiDB 的 `SHOW PROCESSLIST` 与 MySQL 的 `SHOW PROCESSLIST` 显示内容基本一样,不会显示系统进程号,而 ID 表示当前的 session ID。其中 TiDB 的 `show processlist` 和 MySQL 的 `show processlist` 区别如下:

+ 由于 TiDB 是分布式数据库,TiDB server 实例是无状态的 SQL 解析和执行引擎(详情可参考 [TiDB 整体架构](/tidb-architecture.md)),用户使用 MySQL 客户端登录的是哪个 TiDB server ,`show processlist` 就会显示当前连接的这个 TiDB server 中执行的 session 列表,不是整个集群中运行的全部 session 列表;而 MySQL 是单机数据库,`show processlist` 列出的是当前整个 MySQL 数据库的全部执行 SQL 列表。

Expand Down Expand Up @@ -108,9 +110,9 @@ TiDB 支持改变 [per-session](/system-variables.md#tidb_force_priority)、[全

当表的(修改数/当前总行数)大于 `tidb_auto_analyze_ratio` 的时候,会自动触发 `analyze` 语句。`tidb_auto_analyze_ratio` 的默认值为 0.5,即默认开启此功能。为了保险起见,在开启此功能的时候,保证了其最小值为 0.3。但是不能大于等于 `pseudo-estimate-ratio`(默认值为 0.8),否则会有一段时间使用 pseudo 统计信息,建议设置值为 0.5。

## SQL 中如何通过 hint 使用一个具体的 index
## 可以使用 Hints 控制优化器行为吗

MySQL 的用法一致,例如
在 TiDB 中,你可以用多种方法控制查询优化器的默认行为,包括使用 [Optimizer Hints](/optimizer-hints.md) 和 [SQL 执行计划管理 (SPM)](/sql-plan-management.md)。基本用法同 MySQL 中的一致,还包含若干 TiDB 特有的用法,示例如下
`select column_name from table_name use index(index_name)where where_condition;`

## 触发 Information schema is changed 错误的原因?
Expand Down Expand Up @@ -146,11 +148,11 @@ TiDB 在执行 SQL 语句时,会使用当时的 `schema` 来处理该 SQL 语

### TiDB 执行计划解读

详细解读 [理解 TiDB 执行计划](/query-execution-plan.md)。
详细解读[理解 TiDB 执行计划](/query-execution-plan.md)。

### 统计信息收集

详细解读 [统计信息](/statistics.md)。
详细解读[统计信息](/statistics.md)。

### Count 如何加速?

Expand All @@ -162,6 +164,7 @@ Count 就是暴力扫表,提高并发度能显著的提升速度,修改并
- 提升并发度,默认是 10,可以提升到 50 试试,但是一般提升在 2-4 倍之间。
- 测试大数据量的 count。
- 调优 TiKV 配置,可以参考[性能调优](/tune-tikv-memory-performance.md)。
- 可以参考[下推计算结果缓存](/coprocessor-cache.md)。

### 查看当前 DDL 的进度?

Expand Down Expand Up @@ -214,7 +217,7 @@ ID 没什么规律,只要是唯一就行,不过生成的时候,是有一

### 如何打散热点

TiDB 中以 Region 分片来管理数据库,通常来讲,TiDB 的热点指的是 Region 的读写访问热点。而 TiDB 中对于非整数主键或没有主键的表,可以通过设置 `SHARD_ROW_ID_BITS` 来适度分解 Region 分片,以达到打散 Region 热点的效果。详情可参考官网 [SHARD_ROW_ID_BITS](/shard-row-id-bits.md)中的介绍。
TiDB 中以 Region 分片来管理数据库,通常来讲,TiDB 的热点指的是 Region 的读写访问热点。而 TiDB 中对于非整数主键或没有主键的表,可以通过设置 `SHARD_ROW_ID_BITS` 来适度分解 Region 分片,以达到打散 Region 热点的效果。详情可参考官网 [SHARD_ROW_ID_BITS](/shard-row-id-bits.md) 中的介绍。

### TiKV 性能参数调优

Expand Down
6 changes: 5 additions & 1 deletion sql-statements/sql-statement-set-variable.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,11 @@ SHOW SESSION VARIABLES LIKE 'sql_mode';

## MySQL 兼容性

`SET [GLOBAL|SESSION]` 语句与 MySQL 完全兼容。如有任何兼容性差异,请在 GitHub 上提交 [issue](/report-issue.md)。
使用 `SET [GLOBAL|SESSION] <variable>` 更改系统变量上,TiDB 与 MySQL 存在以下差异

* 与 MySQL 不同,TiDB 中使用 `SET GLOBAL` 所作的修改会应用于集群中的全部 TiDB 实例。而在 MySQL 中,修改不会应用于副本。
* TiDB 中的若干变量可读又可设置,这是与 MySQL 相兼容的要求,因为应用程序和连接器常读取 MySQL 变量。例如:JDBC 连接器同时读取和设置缓存查询的参数,尽管并不依赖这一行为。
* 即使在 TiDB 服务器重启后,`SET GLOBAL` 的更改也仍然有效。这样,TiDB 中的 `SET GLOBAL` 更类似于 MySQL 8.0 及更高版本中的 `SET PERSIST`。

## 另请参阅

Expand Down