#![allow(static_mut_refs)]
use remdb::config::{DbConfig, DefaultMemoryAllocator, WALConfig};
use remdb::{RemDb, Result};
static mut DB_MEMORY: [u8; 32 * 1024 * 1024] = [0; 32 * 1024 * 1024];
static ALLOCATOR: DefaultMemoryAllocator = DefaultMemoryAllocator;
fn main() -> Result<()> {
unsafe {
remdb::memory::allocator::init_global_allocator(DB_MEMORY.as_mut_ptr(), DB_MEMORY.len())?;
}
let config = Box::leak(Box::new(DbConfig {
tables: vec![],
total_memory: 16 * 1024 * 1024,
low_power_mode_supported: false,
low_power_max_records: None,
default_max_records: 10000,
memory_allocator: &ALLOCATOR,
wal_config: WALConfig {
log_path: "./wal",
log_mode: remdb::config::LogMode::Async,
checkpoint_interval_ms: 60000,
log_file_size_limit: 16 * 1024 * 1024,
log_prealloc_size: 1024 * 1024,
log_segment_size: 16 * 1024 * 1024,
retained_checkpoints: 3,
max_consecutive_invalid: 100,
skip_threshold: 1000,
skip_block_size: 1024 * 1024,
max_skip_attempts: 3,
compression_type: remdb::config::WALCompressionType::None,
compression_level: 3,
},
time_series_defaults: remdb::time_series::TimeSeriesConfig::DEFAULT,
#[cfg(feature = "ha")]
ha_config: None,
#[cfg(feature = "pubsub")]
pubsub_config: None,
model_worker_config: Default::default(),
}));
let mut db = RemDb::new(config);
db.init()?;
println!("=== 批量插入示例 ===\n");
println!("1. 创建测试表");
db.sql_query(
"CREATE TABLE products (id INT32 PRIMARY KEY, name TEXT, price REAL, stock INT32)",
)?;
println!(" 创建表: products");
println!("\n2. 单条插入 (100 条记录)");
let start = std::time::Instant::now();
for i in 1..=100 {
let sql = format!(
"INSERT INTO products VALUES ({}, 'Product_{}', {}, {})",
i,
i,
i as f64 * 10.0,
i * 10
);
db.sql_query(&sql)?;
}
let single_duration = start.elapsed();
println!(" 单条插入 100 条记录耗时: {:?}", single_duration);
db.sql_query("DELETE FROM products")?;
println!("\n3. SQL 批量插入 (100 条记录)");
let start = std::time::Instant::now();
let mut values_str = String::new();
for i in 1..=100 {
if i > 1 {
values_str.push_str(", ");
}
values_str.push_str(&format!(
"({}, 'Product_{}', {}, {})",
i,
i,
i as f64 * 10.0,
i * 10
));
}
db.sql_query(&format!("INSERT INTO products VALUES {}", values_str))?;
let sql_batch_duration = start.elapsed();
println!(" SQL 批量插入 100 条记录耗时: {:?}", sql_batch_duration);
db.sql_query("DELETE FROM products")?;
println!("\n4. 使用 batch_insert_record API");
let columns: &[&str] = &["id", "name", "price", "stock"];
let batch_size = 100;
let mut id_strings: Vec<String> = Vec::with_capacity(batch_size);
let mut name_strings: Vec<String> = Vec::with_capacity(batch_size);
let mut price_strings: Vec<String> = Vec::with_capacity(batch_size);
let mut stock_strings: Vec<String> = Vec::with_capacity(batch_size);
for i in 1..=batch_size {
id_strings.push(i.to_string());
name_strings.push(format!("Product_{}", i));
price_strings.push((i as f64 * 10.0).to_string());
stock_strings.push((i * 10).to_string());
}
let mut records: Vec<Vec<&str>> = Vec::with_capacity(batch_size);
for i in 0..batch_size {
records.push(vec![
id_strings[i].as_str(),
name_strings[i].as_str(),
price_strings[i].as_str(),
stock_strings[i].as_str(),
]);
}
let records_ref: Vec<&[&str]> = records.iter().map(|v| v.as_slice()).collect();
let start = std::time::Instant::now();
let affected_rows = db.batch_insert_record("products", columns, &records_ref)?;
let api_batch_duration = start.elapsed();
println!(
" batch_insert_record 插入 {} 条记录耗时: {:?}",
affected_rows, api_batch_duration
);
println!("\n5. 验证插入结果");
let result = db.sql_query("SELECT COUNT(*) as count FROM products")?;
println!(" 表中记录数:");
println!("{}", result.to_string());
println!("\n6. 查询前 10 条数据");
let result = db.sql_query("SELECT * FROM products ORDER BY id LIMIT 10")?;
println!("{}", result.to_string());
println!("\n7. 大批量插入测试 (1000 条记录)");
db.sql_query("CREATE TABLE large_data (id INT32 PRIMARY KEY, value TEXT, timestamp INT64)")?;
let batch_size = 1000;
let columns: &[&str] = &["id", "value", "timestamp"];
let mut id_strings: Vec<String> = Vec::with_capacity(batch_size);
let mut value_strings: Vec<String> = Vec::with_capacity(batch_size);
let mut ts_strings: Vec<String> = Vec::with_capacity(batch_size);
for i in 1..=batch_size {
id_strings.push(i.to_string());
value_strings.push(format!("Value_{}", i));
ts_strings.push((i as i64 * 1000).to_string());
}
let mut records: Vec<Vec<&str>> = Vec::with_capacity(batch_size);
for i in 0..batch_size {
records.push(vec![
id_strings[i].as_str(),
value_strings[i].as_str(),
ts_strings[i].as_str(),
]);
}
let records_ref: Vec<&[&str]> = records.iter().map(|v| v.as_slice()).collect();
let start = std::time::Instant::now();
let affected_rows = db.batch_insert_record("large_data", columns, &records_ref)?;
let large_batch_duration = start.elapsed();
println!(
" 批量插入 {} 条记录耗时: {:?}",
affected_rows, large_batch_duration
);
println!("\n8. 插入性能统计");
println!(" 单条插入 100 条: {:?}", single_duration);
println!(" SQL 批量插入 100 条: {:?}", sql_batch_duration);
println!(" API 批量插入 100 条: {:?}", api_batch_duration);
println!(" API 批量插入 1000 条: {:?}", large_batch_duration);
if sql_batch_duration.as_micros() > 0 {
let speedup = single_duration.as_micros() as f64 / sql_batch_duration.as_micros() as f64;
println!(" SQL 批量插入相比单条插入加速: {:.2}x", speedup);
}
println!("\n9. 事务中的批量插入");
db.sql_query("CREATE TABLE transactional_data (id INT32 PRIMARY KEY, data TEXT)")?;
db.sql_query("BEGIN TRANSACTION")?;
let columns: &[&str] = &["id", "data"];
let mut id_strings: Vec<String> = Vec::new();
let mut data_strings: Vec<String> = Vec::new();
for i in 1..=50 {
id_strings.push(i.to_string());
data_strings.push(format!("Data_{}", i));
}
let mut records: Vec<Vec<&str>> = Vec::new();
for i in 0..50 {
records.push(vec![id_strings[i].as_str(), data_strings[i].as_str()]);
}
let records_ref: Vec<&[&str]> = records.iter().map(|v| v.as_slice()).collect();
db.batch_insert_record("transactional_data", columns, &records_ref)?;
println!(" 在事务中批量插入 50 条记录");
db.sql_query("COMMIT")?;
println!(" 提交事务");
let result = db.sql_query("SELECT COUNT(*) as count FROM transactional_data")?;
println!(" 事务提交后的记录数:");
println!("{}", result.to_string());
println!("\n=== 批量插入示例完成 ===");
Ok(())
}