摘要:
在做子查询时, TempTableForSubquery引发大量的memcpy。
本文记录消除memcpy的优化的策略。
逻辑追踪:
火焰图:
memcpy追踪:
(gdb) bt
#0 stonedb::core::Filter::Block::CopyFrom (this=0x7f614677d000, block=..., owner=0x7f6134e4e430) at /data/jenkins/workspace/stonedb5.7-zsl-centos7.9/storage/stonedb/core/filter_block.cpp:68
#1 0x0000000002d5b7a4 in stonedb::core::Filter::Block::Block (this=0x7f614677d000, block=..., owner=0x7f6134e4e430)
at /data/jenkins/workspace/stonedb5.7-zsl-centos7.9/storage/stonedb/core/filter_block.cpp:52
#2 0x0000000002d53660 in stonedb::core::Filter::Filter (this=0x7f6134e4e430, filter=...) at /data/jenkins/workspace/stonedb5.7-zsl-centos7.9/storage/stonedb/core/filter.cpp:106
#3 0x000000000313582d in stonedb::core::DimensionGroupFilter::DimensionGroupFilter (this=0x7f6134a1d9a0, dim=0, f_source=0x7f61349fda50, copy_mode=0, power=16)
at /data/jenkins/workspace/stonedb5.7-zsl-centos7.9/storage/stonedb/core/dimension_group.cpp:35
#4 0x00000000031387fe in stonedb::core::DimensionGroupFilter::Clone (this=0x7f61349fc930, shallow=false)
at /data/jenkins/workspace/stonedb5.7-zsl-centos7.9/storage/stonedb/core/dimension_group.h:142
#5 0x000000000308f6c0 in stonedb::core::MultiIndex::MultiIndex (this=0x7f6134caa700, s=...) at /data/jenkins/workspace/stonedb5.7-zsl-centos7.9/storage/stonedb/core/multi_index.cpp:54
#6 0x00000000030ac3a0 in stonedb::core::ParameterizedFilter::operator= (this=0x7f61349f1380, pf=...)
at /data/jenkins/workspace/stonedb5.7-zsl-centos7.9/storage/stonedb/core/parameterized_filter.cpp:47
#7 0x0000000002dfdb5c in stonedb::core::TempTableForSubquery::ResetToTemplate (this=0x7f61349f1230, rough=true)
at /data/jenkins/workspace/stonedb5.7-zsl-centos7.9/storage/stonedb/core/temp_table.cpp:2168
#8 0x0000000002ea50e4 in stonedb::vcolumn::SubSelectColumn::RoughPrepareSubqCopy (this=0x7f61349f5810, mit=..., sot=stonedb::core::ROW_BASED)
at /data/jenkins/workspace/stonedb5.7-zsl-centos7.9/storage/stonedb/vc/subselect_column.cpp:403
#9 0x0000000002ea5841 in stonedb::vcolumn::SubSelectColumn::RoughIsEmpty (this=0x7f61349f5810, mit=..., sot=stonedb::core::ROW_BASED)
at /data/jenkins/workspace/stonedb5.7-zsl-centos7.9/storage/stonedb/vc/subselect_column.cpp:487
#10 0x0000000003055ee2 in stonedb::core::Descriptor::RoughCheckSubselectCondition (this=0x7f61349ff2b0, mit=..., sot=stonedb::core::ROW_BASED)
at /data/jenkins/workspace/stonedb5.7-zsl-centos7.9/storage/stonedb/core/descriptor.cpp:1189
#11 0x00000000030527ea in stonedb::core::Descriptor::EvaluatePackImpl (this=0x7f61349ff2b0, mit=...) at /data/jenkins/workspace/stonedb5.7-zsl-centos7.9/storage/stonedb/core/descriptor.cpp:845
#12 0x0000000003052a58 in stonedb::core::Descriptor::EvaluatePack (this=0x7f61349ff2b0, mit=...) at /data/jenkins/workspace/stonedb5.7-zsl-centos7.9/storage/stonedb/core/descriptor.cpp:898
#13 0x00000000030b46de in stonedb::core::ParameterizedFilter::ApplyDescriptor (this=0x7f61349ef110, desc_number=1, limit=-1)
at /data/jenkins/workspace/stonedb5.7-zsl-centos7.9/storage/stonedb/core/parameterized_filter.cpp:1365
#14 0x00000000030b2b37 in stonedb::core::ParameterizedFilter::UpdateMultiIndex (this=0x7f61349ef110, count_only=false, limit=-1)
at /data/jenkins/workspace/stonedb5.7-zsl-centos7.9/storage/stonedb/core/parameterized_filter.cpp:1065
#15 0x0000000002d731f7 in stonedb::core::Query::Preexecute (this=0x7f6501cb2800, qu=..., sender=0x7f61349e6bb0, display_now=true)
at /data/jenkins/workspace/stonedb5.7-zsl-centos7.9/storage/stonedb/core/query.cpp:777
#16 0x0000000002d44a2e in stonedb::core::Engine::Execute (this=0x7779df0, thd=0x7f6134913df0, lex=0x7f6134916118, result_output=0x7f61340091f0, unit_for_union=0x0)
at /data/jenkins/workspace/stonedb5.7-zsl-centos7.9/storage/stonedb/core/engine_execute.cpp:421
#17 0x0000000002d43ce2 in stonedb::core::Engine::HandleSelect (this=0x7779df0, thd=0x7f6134913df0, lex=0x7f6134916118, result=@0x7f6501cb2d18: 0x7f61340091f0, setup_tables_done_option=0,
res=@0x7f6501cb2d14: 0, optimize_after_sdb=@0x7f6501cb2d0c: 1, sdb_free_join=@0x7f6501cb2d10: 1, with_insert=0)
at /data/jenkins/workspace/stonedb5.7-zsl-centos7.9/storage/stonedb/core/engine_execute.cpp:232
#18 0x0000000002e2c4df in stonedb::dbhandler::SDB_HandleSelect (thd=0x7f6134913df0, lex=0x7f6134916118, result=@0x7f6501cb2d18: 0x7f61340091f0, setup_tables_done_option=0, res=@0x7f6501cb2d14: 0,
optimize_after_sdb=@0x7f6501cb2d0c: 1, sdb_free_join=@0x7f6501cb2d10: 1, with_insert=0) at /data/jenkins/workspace/stonedb5.7-zsl-centos7.9/storage/stonedb/handler/ha_rcengine.cpp:82
#19 0x000000000246fe5a in execute_sqlcom_select (thd=0x7f6134913df0, all_tables=0x7f6134015440) at /data/jenkins/workspace/stonedb5.7-zsl-centos7.9/sql/sql_:5182
#20 0x00000000024691de in mysql_execute_command (thd=0x7f6134913df0, first_level=true) at /data/jenkins/workspace/stonedb5.7-zsl-centos7.9/sql/sql_:2831
#21 0x0000000002470e23 in mysql_parse (thd=0x7f6134913df0, parser_state=0x7f6501cb3eb0) at /data/jenkins/workspace/stonedb5.7-zsl-centos7.9/sql/sql_:5621
#22 0x00000000024660bb in dispatch_command (thd=0x7f6134913df0, com_data=0x7f6501cb4650, command=COM_QUERY) at /data/jenkins/workspace/stonedb5.7-zsl-centos7.9/sql/sql_:1495
#23 0x0000000002464fe7 in do_command (thd=0x7f6134913df0) at /data/jenkins/workspace/stonedb5.7-zsl-centos7.9/sql/sql_:1034
#24 0x0000000002597c03 in handle_connection (arg=0x7ea03b0) at /data/jenkins/workspace/stonedb5.7-zsl-centos7.9/sql/conn_handler/connection_handler_per_:313
#25 0x0000000002c7b834 in pfs_spawn_thread (arg=0x939e3f0) at /data/jenkins/workspace/stonedb5.7-zsl-centos7.9/storage/perfschema/:2197
#26 0x00007f65514c6ea5 in start_thread (arg=0x7f6501cb5700) at pthread_create.c:307
#27 0x00007f654f8fdb0d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:111
MultiIndex::MultiIndex(const MultiIndex &s) : m_conn(s.m_conn) {
p_power = s.p_power;
no_dimensions = s.no_dimensions;
no_tuples = s.no_tuples;
no_tuples_too_big = s.no_tuples_too_big;
if (no_dimensions > 0) {
dim_size = new int64_t[no_dimensions];
group_for_dim = new DimensionGroup *[no_dimensions];
group_num_for_dim = new int[no_dimensions];
used_in_output = s.used_in_output;
can_be_distinct = s.can_be_distinct;
for (uint i = 0; i < s.dim_groups.size(); i++) dim_groups.push_back(s.dim_groups[i]->Clone(false));
for (int i = 0; i < no_dimensions; i++) dim_size[i] = s.dim_size[i];
FillGroupForDim();
} else {
dim_size = NULL;
group_for_dim = NULL;
group_num_for_dim = NULL;
}
iterator_lock = 0;
}
for (uint i = 0; i < s.dim_groups.size(); i++) dim_groups.push_back(s.dim_groups[i]->Clone(false));
方案: 物化DimensionGroup
思路:
- 在ResetToTemplate时, 对TempTableForSubquery::template_filter做值拷贝, 从此处入手
- 预先对template_filter的DimensionGroup做物化
- 后续从template_filter值拷贝时, 打开DimensionGroup的物化表