Skip to content

Commit 2a83ebc

Browse files
Minor improvement (#1060)
* Improve, use INNER JOINS instead of LEFT JOINS when the join result is used in where * Refactor * Revert log query optimizations * Modernize
1 parent fd5a3e2 commit 2a83ebc

2 files changed

Lines changed: 48 additions & 76 deletions

File tree

logdb/logdb.go

Lines changed: 39 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import (
1010
"database/sql"
1111
"fmt"
1212
"math/big"
13-
"strings"
1413

1514
sqlite3 "github.com/mattn/go-sqlite3"
1615
"github.com/vechain/thor/v2/block"
@@ -22,8 +21,6 @@ const (
2221
refIDQuery = "(SELECT id FROM ref WHERE data=?)"
2322
)
2423

25-
var toMax, _ = newSequence(MaxBlockNumber, 0, 0)
26-
2724
type LogDB struct {
2825
path string
2926
driverVersion string
@@ -98,7 +95,7 @@ func (db *LogDB) Path() string {
9895

9996
func (db *LogDB) FilterEvents(ctx context.Context, filter *EventFilter) ([]*Event, error) {
10097
const query = `SELECT e.seq, r0.data, e.blockTime, r1.data, r2.data, e.clauseIndex, r3.data, r4.data, r5.data, r6.data, r7.data, r8.data, e.data
101-
FROM event e
98+
FROM (%v) e
10299
LEFT JOIN ref r0 ON e.blockID = r0.id
103100
LEFT JOIN ref r1 ON e.txID = r1.id
104101
LEFT JOIN ref r2 ON e.txOrigin = r2.id
@@ -107,162 +104,147 @@ FROM event e
107104
LEFT JOIN ref r5 ON e.topic1 = r5.id
108105
LEFT JOIN ref r6 ON e.topic2 = r6.id
109106
LEFT JOIN ref r7 ON e.topic3 = r7.id
110-
LEFT JOIN ref r8 ON e.topic4 = r8.id
111-
%v
112-
`
107+
LEFT JOIN ref r8 ON e.topic4 = r8.id`
113108

114109
if filter == nil {
115-
where := fmt.Sprintf(" WHERE e.seq >= 0 AND e.seq <= %v", toMax)
116-
return db.queryEvents(ctx, fmt.Sprintf(query, where))
110+
return db.queryEvents(ctx, fmt.Sprintf(query, "event"))
117111
}
118112

119113
metricsHandleEventsFilter(filter)
120114

121115
var (
122-
whereOrderLimit strings.Builder
123-
args []any
116+
subQuery = "SELECT seq FROM event WHERE 1"
117+
args []any
124118
)
125119

126120
if filter.Range != nil {
127-
whereOrderLimit.WriteString(" WHERE e.seq >= ?")
121+
subQuery += " AND seq >= ?"
128122
from, err := newSequence(filter.Range.From, 0, 0)
129123
if err != nil {
130124
return nil, err
131125
}
132126
args = append(args, from)
133127
if filter.Range.To >= filter.Range.From {
134-
whereOrderLimit.WriteString(" AND e.seq <= ?")
128+
subQuery += " AND seq <= ?"
135129
to, err := newSequence(filter.Range.To, txIndexMask, logIndexMask)
136130
if err != nil {
137131
return nil, err
138132
}
139133
args = append(args, to)
140134
}
141-
} else {
142-
whereOrderLimit.WriteString(fmt.Sprintf(" WHERE e.seq >= 0 AND e.seq <= %v", toMax))
143135
}
144136

145137
if len(filter.CriteriaSet) > 0 {
146-
whereOrderLimit.WriteString(" AND (")
138+
subQuery += " AND ("
147139

148140
for i, c := range filter.CriteriaSet {
149141
cond, cargs := c.toWhereCondition()
150142
if i > 0 {
151-
whereOrderLimit.WriteString(" OR")
143+
subQuery += " OR"
152144
}
153-
whereOrderLimit.WriteString(" (")
154-
whereOrderLimit.WriteString(cond)
155-
whereOrderLimit.WriteString(")")
145+
subQuery += " (" + cond + ")"
156146
args = append(args, cargs...)
157147
}
158-
whereOrderLimit.WriteString(")")
148+
subQuery += ")"
159149
}
160150

161151
// if there is limit option, set order inside subquery
162152
if filter.Options != nil {
163153
if filter.Order == DESC {
164-
whereOrderLimit.WriteString(" ORDER BY e.seq DESC ")
154+
subQuery += " ORDER BY seq DESC "
165155
} else {
166-
whereOrderLimit.WriteString(" ORDER BY e.seq ASC ")
156+
subQuery += " ORDER BY seq ASC "
167157
}
168-
whereOrderLimit.WriteString(" LIMIT ?, ?")
158+
subQuery += " LIMIT ?, ?"
169159
args = append(args, filter.Options.Offset, filter.Options.Limit)
170160
}
171161

172-
eventQuery := strings.Builder{}
173-
eventQuery.WriteString(fmt.Sprintf(query, whereOrderLimit.String()))
162+
subQuery = "SELECT e.* FROM (" + subQuery + ") s LEFT JOIN event e ON s.seq = e.seq"
163+
164+
eventQuery := fmt.Sprintf(query, subQuery)
174165
// if there is no limit option, set order outside
175166
if filter.Options == nil {
176167
if filter.Order == DESC {
177-
eventQuery.WriteString(" ORDER BY e.seq DESC ")
168+
eventQuery += " ORDER BY seq DESC "
178169
} else {
179-
eventQuery.WriteString(" ORDER BY e.seq ASC ")
170+
eventQuery += " ORDER BY seq ASC "
180171
}
181172
}
182-
183-
return db.queryEvents(ctx, eventQuery.String(), args...)
173+
return db.queryEvents(ctx, eventQuery, args...)
184174
}
185175

186176
func (db *LogDB) FilterTransfers(ctx context.Context, filter *TransferFilter) ([]*Transfer, error) {
187177
const query = `SELECT t.seq, r0.data, t.blockTime, r1.data, r2.data, t.clauseIndex, r3.data, r4.data, t.amount
188-
FROM transfer t
178+
FROM (%v) t
189179
LEFT JOIN ref r0 ON t.blockID = r0.id
190180
LEFT JOIN ref r1 ON t.txID = r1.id
191181
LEFT JOIN ref r2 ON t.txOrigin = r2.id
192182
LEFT JOIN ref r3 ON t.sender = r3.id
193-
LEFT JOIN ref r4 ON t.recipient = r4.id
194-
%v`
183+
LEFT JOIN ref r4 ON t.recipient = r4.id`
195184

196185
if filter == nil {
197-
where := fmt.Sprintf(" WHERE t.seq >= 0 AND t.seq <= %v", toMax)
198-
199-
return db.queryTransfers(ctx, fmt.Sprintf(query, where))
186+
return db.queryTransfers(ctx, fmt.Sprintf(query, "transfer"))
200187
}
201188

202189
metricsHandleCommonFilter(filter.Options, filter.Order, len(filter.CriteriaSet), "transfer")
203190

204191
var (
205-
whereOrderLimit strings.Builder
206-
args []any
192+
subQuery = "SELECT seq FROM transfer WHERE 1"
193+
args []any
207194
)
208195

209196
if filter.Range != nil {
210-
whereOrderLimit.WriteString(" WHERE t.seq >= ?")
197+
subQuery += " AND seq >= ?"
211198
from, err := newSequence(filter.Range.From, 0, 0)
212199
if err != nil {
213200
return nil, err
214201
}
215202
args = append(args, from)
216203
if filter.Range.To >= filter.Range.From {
217-
whereOrderLimit.WriteString(" AND t.seq <= ?")
204+
subQuery += " AND seq <= ?"
218205
to, err := newSequence(filter.Range.To, txIndexMask, logIndexMask)
219206
if err != nil {
220207
return nil, err
221208
}
222209
args = append(args, to)
223210
}
224-
} else {
225-
whereOrderLimit.WriteString(fmt.Sprintf(" WHERE t.seq >= 0 AND t.seq <= %v", toMax))
226211
}
227212

228213
if len(filter.CriteriaSet) > 0 {
229-
whereOrderLimit.WriteString(" AND (")
214+
subQuery += " AND ("
230215
for i, c := range filter.CriteriaSet {
231216
cond, cargs := c.toWhereCondition()
232217
if i > 0 {
233-
whereOrderLimit.WriteString(" OR")
218+
subQuery += " OR"
234219
}
235-
whereOrderLimit.WriteString(" (")
236-
whereOrderLimit.WriteString(cond)
237-
whereOrderLimit.WriteString(")")
220+
subQuery += " (" + cond + ")"
238221
args = append(args, cargs...)
239222
}
240-
whereOrderLimit.WriteString(")")
223+
subQuery += ")"
241224
}
242225

243226
// if there is limit option, set order inside subquery
244227
if filter.Options != nil {
245228
if filter.Order == DESC {
246-
whereOrderLimit.WriteString(" ORDER BY t.seq DESC")
229+
subQuery += " ORDER BY seq DESC"
247230
} else {
248-
whereOrderLimit.WriteString(" ORDER BY t.seq ASC")
231+
subQuery += " ORDER BY seq ASC"
249232
}
250-
whereOrderLimit.WriteString(" LIMIT ?, ?")
233+
subQuery += " LIMIT ?, ?"
251234
args = append(args, filter.Options.Offset, filter.Options.Limit)
252235
}
253236

254-
transferQuery := strings.Builder{}
255-
transferQuery.WriteString(fmt.Sprintf(query, whereOrderLimit.String()))
237+
subQuery = "SELECT e.* FROM (" + subQuery + ") s LEFT JOIN transfer e ON s.seq = e.seq"
238+
transferQuery := fmt.Sprintf(query, subQuery)
256239
// if there is no limit option, set order outside
257240
if filter.Options == nil {
258241
if filter.Order == DESC {
259-
transferQuery.WriteString(" ORDER BY t.seq DESC ")
242+
transferQuery += " ORDER BY seq DESC "
260243
} else {
261-
transferQuery.WriteString(" ORDER BY t.seq ASC ")
244+
transferQuery += " ORDER BY seq ASC "
262245
}
263246
}
264-
265-
return db.queryTransfers(ctx, transferQuery.String(), args...)
247+
return db.queryTransfers(ctx, transferQuery, args...)
266248
}
267249

268250
func (db *LogDB) queryEvents(ctx context.Context, query string, args ...any) ([]*Event, error) {

logdb/types.go

Lines changed: 9 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ package logdb
88
import (
99
"fmt"
1010
"math/big"
11-
"strings"
1211

1312
"github.com/vechain/thor/v2/thor"
1413
)
@@ -66,21 +65,18 @@ type EventCriteria struct {
6665
}
6766

6867
func (c *EventCriteria) toWhereCondition() (cond string, args []any) {
69-
builder := strings.Builder{}
68+
cond = "1"
7069
if c.Address != nil {
71-
builder.WriteString(" r3.data = ?")
70+
cond += " AND address = " + refIDQuery
7271
args = append(args, c.Address.Bytes())
7372
}
7473
for i, topic := range c.Topics {
7574
if topic != nil {
76-
if builder.String() != "" {
77-
builder.WriteString(" AND ")
78-
}
79-
builder.WriteString(fmt.Sprintf(" r%v.data = ?", i+4))
75+
cond += fmt.Sprintf(" AND topic%v = ", i) + refIDQuery
8076
args = append(args, removeLeadingZeros(topic.Bytes()))
8177
}
8278
}
83-
return builder.String(), args
79+
return
8480
}
8581

8682
// EventFilter filter
@@ -98,26 +94,20 @@ type TransferCriteria struct {
9894
}
9995

10096
func (c *TransferCriteria) toWhereCondition() (cond string, args []any) {
101-
builder := strings.Builder{}
97+
cond = "1"
10298
if c.TxOrigin != nil {
103-
builder.WriteString(" r2.data = ?")
99+
cond += " AND txOrigin = " + refIDQuery
104100
args = append(args, c.TxOrigin.Bytes())
105101
}
106102
if c.Sender != nil {
107-
if builder.String() != "" {
108-
builder.WriteString(" AND ")
109-
}
110-
builder.WriteString(" r3.data = ?")
103+
cond += " AND sender = " + refIDQuery
111104
args = append(args, c.Sender.Bytes())
112105
}
113106
if c.Recipient != nil {
114-
if builder.String() != "" {
115-
builder.WriteString(" AND ")
116-
}
117-
builder.WriteString(" r4.data = ?")
107+
cond += " AND recipient = " + refIDQuery
118108
args = append(args, c.Recipient.Bytes())
119109
}
120-
return builder.String(), args
110+
return
121111
}
122112

123113
type TransferFilter struct {

0 commit comments

Comments
 (0)