| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Optimize timezone-aware query functions (timestamp_floor\_\*\_tz, format_timestamp_tz)
Problem: queries using timezone functions on a non-Moscow/non-UTC zone (e.g.
Europe/Bucharest) ran 10-20x slower than their non-timezone equivalents. For
Moscow/UTC a lookup table handles the conversion; for any other zone the code
falls back to live cctz calls.
Cause, confirmed by flamegraph and code:
1. NDatetime::ToCivilTime performed two independent timezone lookups per call.
cctz::convert(tp, tz) is defined as tz.lookup(tp).cs, and the function then
called tz.lookup(tp) again for the offset/is_dst fields. Both pieces of data
are already present in a single absolute_lookup result.
2. TimestampFloorDayTZInternal (and Month/Quarter/Year variants) located the
start of the period via a binary search that called ToCivilTime on every
iteration — \~18 iterations for the day case. Combined with (1) that is \~38
cctz lookups per call, and timestamp_floor_day_tz appears twice per row in a
typical WHERE clause.
* Changelog entry
Type: fix
1. ToCivilTime now does a single tz.lookup(tp) and reuses both cs and the
offset/is_dst fields. Behavior is identical; affects all callers.
2. TimestampFloor\{Day,Month,Quarter,Year\}TZ compute the period start directly
(subtract the civil time-of-day, or build the first second of the period and
convert it back), then verify the result. The binary search is kept as a
fallback for the rare days that do not start at midnight (DST transitions at
00:00, historical offset shifts), so results are unchanged.
commit_hash:295ee82832ab2a4a35920067e7c063d6992bb083
|