Performance Tuning Best Practices
This document introduces some best practices for using TiDB databases.
DML best practices
This section describes the best practices involved when you use DML with TiDB.
Use multi-row statements
When you need to modify multiple rows of table, it is recommended to use multi-row statements:
INSERT INTO t VALUES (1, 'a'), (2, 'b'), (3, 'c');
DELETE FROM t WHERE id IN (1, 2, 3);
It is not recommended to use multiple single-row statements:
INSERT INTO t VALUES (1, 'a');
INSERT INTO t VALUES (2, 'b');
INSERT INTO t VALUES (3, 'c');
DELETE FROM t WHERE id = 1;
DELETE FROM t WHERE id = 2;
DELETE FROM t WHERE id = 3;
Use PREPARE
When you need to execute a SQL statement for multiple times, it is recommended to use the PREPARE
statement to avoid the overhead of repeatedly parsing the SQL syntax.
- Golang
- Java
func BatchInsert(db *sql.DB) error {
stmt, err := db.Prepare("INSERT INTO t (id) VALUES (?), (?), (?), (?), (?)")
if err != nil {
return err
}
for i := 0; i < 1000; i += 5 {
values := []interface{}{i, i + 1, i + 2, i + 3, i + 4}
_, err = stmt.Exec(values...)
if err != nil {
return err
}
}
return nil
}
public void batchInsert(Connection connection) throws SQLException {
PreparedStatement statement = connection.prepareStatement(
"INSERT INTO `t` (`id`) VALUES (?), (?), (?), (?), (?)");
for (int i = 0; i < 1000; i ++) {
statement.setInt(i % 5 + 1, i);
if (i % 5 == 4) {
statement.executeUpdate();
}
}
}
Do not execute the PREPARE
statement repeatedly. Otherwise, the execution efficiency cannot be improved.
Only query the columns you need
If you do not need data from all columns, do not use SELECT *
to return all columns data. The following query is inefficient:
SELECT * FROM books WHERE title = 'Marian Yost';
You should only query the columns you need. For example:
SELECT title, price FROM books WHERE title = 'Marian Yost';
Use bulk delete
When you delete a large amount of data, it is recommended to use bulk delete.
Use bulk update
When you update a large amount of data, it is recommended to use bulk update.
Use TRUNCATE
instead of DELETE
for full table data
When you need to delete all data from a table, it is recommended to use the TRUNCATE
statement:
TRUNCATE TABLE t;
It is not recommended to use DELETE
for full table data:
DELETE FROM t;
DDL best practices
This section describes the best practices involved when using TiDB's DDL.
Primary key best practices
See the rules to follow when selecting the primary key.
Index best practices
See Index Best Practices.
Add index best practices
TiDB supports the online index add operation. You can use ADD INDEX or CREATE INDEX statement to add an index. It does not block data reads and writes in the table. You can adjust the concurrency and the batch size during the re-organize
phase of the index add operation by modifying the following system variables:
To reduce the impact on the online application, the default speed of add index operation is slow. When the target column of add index operation only involves read load or is not directly related to online workload, you can appropriately increase the value of the above variables to speed up the add index operation:
SET @@global.tidb_ddl_reorg_worker_cnt = 16;
SET @@global.tidb_ddl_reorg_batch_size = 4096;
When the target column of the add index operation is updated frequently (including UPDATE
, INSERT
and DELETE
), increasing the above variables causes more write conflicts, which impacts the online workload. Accordingly, the add index operation might take a long time to complete due to constant retries. In this case, it is recommended to decrease the value of the above variables to avoid write conflicts with the online application:
SET @@global.tidb_ddl_reorg_worker_cnt = 4;
SET @@global.tidb_ddl_reorg_batch_size = 128;
Transaction conflicts
For how to locate and resolve transaction conflicts, see Troubleshoot Lock Conflicts.
Best practices for developing Java applications with TiDB
See Best Practices for Developing Java Applications with TiDB.