Poor Ingestion Performance

Note:
This topic has been translated from a Chinese forum by GPT and might contain errors.

Original topic: 入库性能较差

| username: TiDBer_ZfFjmcZo

[TiDB Usage Environment] Production Environment / Testing / Poc
[TiDB Version]
[Reproduction Path] Using load to batch load CSV files or using batch on id limit 10000 insert into t2 select * from t1 for import
[Encountered Issues: Problem Phenomenon and Impact] The data import is relatively slow. In the same scenario, the performance of GP is about 10 times that of TiDB. Is there room for optimization?
Additionally, the screenshot shows the CPU and memory usage of TiKV through monitoring, with significant differences in usage rates (deployed on the same node with the same IP). Why does this phenomenon occur?
[Resource Configuration]
[Attachments: Screenshots/Logs/Monitoring]

| username: 托马斯滑板鞋 | Original post link

Has the table been pre-sharded? Is the speed the same for one-time file import and insert into select *?

| username: dba-kit | Original post link

If it’s a CSV file, I recommend using tidb-lightning to handle it. It writes directly to TiKV and is extremely fast.

| username: TiDBer_ZfFjmcZo | Original post link

I tested and found that insert into is faster than load. Isn’t sharding done automatically?

| username: dba-kit | Original post link

Refer to the official documentation here: TiDB Lightning 配置参数 | PingCAP 文档中心. There are quite a few adjustments that can be made to the CSV format, and most of them can be accommodated.

| username: TiDBer_ZfFjmcZo | Original post link

I’ve used it, it’s similar to load. The performance isn’t good either.

| username: 托马斯滑板鞋 | Original post link

  1. Is TiDB Lightning using the local mode? (This method is theoretically the fastest)
  2. Pre-sharding can reduce the overhead of automatic table sharding and save time.
    P.S: If it’s slow, you can split the CSV into multiple parts and run them concurrently, as long as the name prefixes are the same. Refer to: TiDB Lightning 快速上手 | PingCAP 文档中心
| username: dba-kit | Original post link

It’s unlikely. Are you not using the mode that writes directly to TiKV? You can check the documentation at 物理导入模式 | PingCAP 文档中心. Based on my experience, the import speed is generally proportional to the number of CPU cores on the tidb-lightning machine.

| username: TiDBer_ZfFjmcZo | Original post link

I just checked, it is using the local mode. I’ll test pre-sharding and concurrency.

| username: dba-kit | Original post link

What is the configuration of the machine where your tidb-lightning is located? The local mode has relatively high configuration requirements for the lightning machine. Generally, the higher the configuration, the faster the import speed.

| username: TiDBer_ZfFjmcZo | Original post link

The local mode is what you mentioned as direct writing, right? From what I understand, Lightning essentially also loads in batches. It just so happens that I measured consistent results for both methods.

| username: 托马斯滑板鞋 | Original post link

What is your current import speed? It should be shown in the lightning logs. What is the theoretical peak of your storage IO? What do you expect it to be? If it doesn’t work, split the CSV file into two parts with the same prefix name, then use lightning to import with concurrency set to 2 and see if the speed improves.

| username: TiDBer_ZfFjmcZo | Original post link

There is no separate machine; it is deployed on a node in the cluster. The CPU is definitely not fully utilized.

| username: TiDBer_ZfFjmcZo | Original post link

Currently, it’s 2w/s. IO usage is only at 20%. Concurrency might be effective, will verify later. How can we optimize this batch on id limit 10000 insert into t2 select * from t1?

| username: 托马斯滑板鞋 | Original post link

I suggest using Lightning to export everything and then import it into the new table, this is the fastest way;
The method of “insert into t2 select *” has been encountered in other databases before, and it is very slow. The principle is probably because it processes data row by row (similar to a cursor). I wonder if TiDB is the same? (The processing method is also batch export to local and then import)

| username: buddyyuan | Original post link

When using load data, it is best to specify tidb_dml_batch_size and set tidb_dml_batch_size = 20000.

| username: dba-kit | Original post link

Batch DML is actually very inefficient. This is mainly to avoid large transactions exceeding TiDB’s default memory limit. It’s not even as fast as dividing chunks yourself and running several select into operations.

| username: TiDBer_ZfFjmcZo | Original post link

There is an effect, it can reach 30,000 per second. In comparison, it is still much worse.

| username: buddyyuan | Original post link

You are still using a single thread to load data. Split the file into batches and use multiple threads to load data, and the speed will improve.

| username: 人如其名 | Original post link

A single-threaded import speed of 30,000 rows per second is already quite high; mine is usually around 20,000 rows per second. :grin:
TiDB needs to run more concurrent processes to be faster. Alternatively, using Lightning’s local mode is much faster. If you can see SQL statements in TiDB’s processlist, then it’s not in local mode.