-
Notifications
You must be signed in to change notification settings - Fork 0
/
total_energy.cc
139 lines (128 loc) · 5.03 KB
/
total_energy.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
#include <iostream>
#include <string>
#include <memory>
#include <chrono>
#include <thread>
#include "mariadb/conncpp.hpp"
// 实际修改的记录条数,(100W条耗时太长)
// #define RECORD_NUM (10 * 10000)
#define RECORD_NUM (10 * 10000)
sql::Driver *driver = sql::mariadb::get_driver_instance();
// Configure Connection
sql::SQLString url("jdbc:mariadb://127.0.0.1/atec2022");
sql::Properties properties(
{
{"user", "root"},
{"password", "111111"},
{"allowLocalInfile", "true"}
}
);
std::shared_ptr<sql::Connection> get_conn() {
std::shared_ptr<sql::Connection> conn(driver->connect(url, properties));
return conn;
}
void create_total_energy() {
auto conn = get_conn();
{
std::unique_ptr<sql::PreparedStatement> stmt(conn->prepareStatement(
"drop table total_energy;"
));
stmt->executeQuery();
std::cout << "success: start drop table total_energy" << std::endl;
}
{
std::unique_ptr<sql::PreparedStatement> stmt(conn->prepareStatement(
"create table total_energy\
(\
id int auto_increment\
primary key,\
gmt_create datetime null,\
gmt_modified datetime null,\
user_id varchar(64) null,\
total_energy int null,\
constraint total_energy_pk\
unique (user_id)\
);"
));
stmt->executeQuery();
std::cout << "success: create table total_energy" << std::endl;
}
{
std::unique_ptr<sql::PreparedStatement> stmt(conn->prepareStatement(
"LOAD DATA LOCAL INFILE '../total-energy_10W.csv' INTO TABLE total_energy FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '\"' LINES TERMINATED BY '\n';"
));
using namespace std::chrono_literals;
auto start = std::chrono::high_resolution_clock::now();
stmt->executeQuery();
auto end = std::chrono::high_resolution_clock::now();
std::chrono::duration<double, std::milli> elapsed = end-start;
std::cout << "success: create table total_energy, elapsed time: " << elapsed.count() << "ms" << std::endl;
}
}
void totalEnergy_update(const std::shared_ptr<sql::Connection> &conn, const char *user_id, int totalEnergy) {
std::unique_ptr<sql::PreparedStatement> stmt(conn->prepareStatement(
"update total_energy set total_energy = ? where user_id = ?"
));
stmt->setInt(1, totalEnergy);
stmt->setString(2, user_id);
stmt->executeUpdate();
}
void multi_statement_update(bool is_single_txn) {
auto conn = get_conn();
conn->setAutoCommit(!is_single_txn);
for (int id = 0; id < RECORD_NUM; id++) {
std::string user_id = std::to_string(id);
totalEnergy_update(conn, /* user_id */user_id.c_str(), /* totalEnergy */id);
}
if (is_single_txn) {
conn->commit();
}
}
void multi_statement_multi_txn_update() {
using namespace std::chrono_literals;
auto start = std::chrono::high_resolution_clock::now();
multi_statement_update(false);
auto end = std::chrono::high_resolution_clock::now();
std::chrono::duration<double, std::milli> elapsed = end-start;
std::cout << "success: multi_statement_multi_txn_update, elapsed time: " << elapsed.count() << " ms\n";
}
void multi_statement_single_txn_update() {
using namespace std::chrono_literals;
auto start = std::chrono::high_resolution_clock::now();
multi_statement_update(true);
auto end = std::chrono::high_resolution_clock::now();
std::chrono::duration<double, std::milli> elapsed = end-start;
std::cout << "success: multi_statement_single_txn_update, elapsed time: " << elapsed.count() << " ms\n";
}
void rewrite_update() {
auto conn = get_conn();
using namespace std::chrono_literals;
auto start = std::chrono::high_resolution_clock::now();
std::string stmt_str;
stmt_str.reserve(23000000);
stmt_str = "update total_energy as m, ( select 0 as c1, \"0\" as c2 ";
for (int id = 1; id < RECORD_NUM; id++) {
stmt_str += "union all select "+ std::to_string(id) +", "+ std::to_string(id) + " ";
}
stmt_str += ") as r set m.total_energy = r.c1 where m.user_id = r.c2;";
std::unique_ptr<sql::PreparedStatement> stmt(conn->prepareStatement(stmt_str));
// note(wq): 下列做法,非常费时!
// for (int i = 0; i < RECORD_NUM; i++) {
// stmt->setInt(2 * i + 1, i);
// stmt->setString(2 * i + 2, std::to_string(i));
// }
std::cout << "--------------------------------------------\n";
stmt->executeQuery();
auto end = std::chrono::high_resolution_clock::now();
std::chrono::duration<double, std::milli> elapsed = end-start;
std::cout << "success: rewrite_update, elapsed time: " << elapsed.count() << " ms\n";
}
int main() {
create_total_energy();
multi_statement_single_txn_update();
create_total_energy();
multi_statement_multi_txn_update();
create_total_energy();
rewrite_update();
return 0;
}