The code in create_schema_table() has switch's and if's testing MYSQL_TYPE_XXX.
This is not friendly to data type plugins.
Additionally, when schema tables are created in two steps:
On the first step, Items are created from ST_FIELD_INFO
On the second step, these Items create Fields
which is slow.
Let's do the following:
Add a new method in Type_handler:
virtual Field *make_schema_field(TABLE *table,
const Record_addr &addr,
const ST_FIELD_INFO &def,
bool show_field) const
Change the logic to create Fields directly from ST_FIELD_INFO.
For that purpose, and to be able to reuse the code in a convenient way, wrap create_tmp_table() into a class Create_tmp_table with approximately these methods:
class Create_tmp_table
{
public:
...
// The former beginning of create_tmp_table()
TABLE *start(THD *thd,
TMP_TABLE_PARAM *param,
const LEX_CSTRING *table_alias);
// The former loop of create_tmp_table(), adding fields into the table
bool add_fields(THD *thd, TABLE *table,
TMP_TABLE_PARAM *param, List<Item> &fields);
// A new code adding fields directly from ST_FIELD_INFO
bool add_schema_fields(THD *thd, TABLE *table,
TMP_TABLE_PARAM *param,
const ST_SCHEMA_TABLE &schema_table,
const MY_BITMAP &bitmap);
// The forder end of create_tmp_table(), after the loop adding fields.
The code in create_schema_table() has switch's and if's testing MYSQL_TYPE_XXX.
This is not friendly to data type plugins.
Additionally, when schema tables are created in two steps:
- On the first step, Items are created from ST_FIELD_INFO
- On the second step, these Items create Fields
which is slow.
Let's do the following:
- Add a new method in Type_handler:
{code:sql}
virtual Field *make_schema_field(TABLE *table,
const Record_addr &addr,
const ST_FIELD_INFO &def,
bool show_field) const
{code}
- Change the logic to create Fields directly from ST_FIELD_INFO.
- For that purpose, and to be able to reuse the code in a convenient way, wrap create_tmp_table() into a class Create_tmp_table with approximately with methods:
{code:cpp}
class Create_tmp_table
{
public:
...
// The former beginning of {{create_tmp_table()}}
TABLE *start(THD *thd,
TMP_TABLE_PARAM *param,
const LEX_CSTRING *table_alias);
// The former loop of {{create_tmp_table()}} adding fields
bool add_fields(THD *thd, TABLE *table,
TMP_TABLE_PARAM *param, List<Item> &fields);
// A new code adding fields directly from ST_FIELD_INFO
bool add_schema_fields(THD *thd, TABLE *table,
TMP_TABLE_PARAM *param,
const ST_SCHEMA_TABLE &schema_table,
const MY_BITMAP &bitmap);
// The forder end of {{create_tmp_table()}}, after the loop.
bool finalize(THD *thd, TABLE *table, TMP_TABLE_PARAM *param,
bool do_not_open, bool keep_row_order);
};
{code}
- Remove method Item::create_field_for_schema()
- Remove class Item_return_date_time
- Remove class Item_blob
The code in create_schema_table() has switch's and if's testing MYSQL_TYPE_XXX.
This is not friendly to data type plugins.
Additionally, when schema tables are created in two steps:
- On the first step, Items are created from ST_FIELD_INFO
- On the second step, these Items create Fields
which is slow.
Let's do the following:
- Add a new method in Type_handler:
{code:sql}
virtual Field *make_schema_field(TABLE *table,
const Record_addr &addr,
const ST_FIELD_INFO &def,
bool show_field) const
{code}
- Change the logic to create Fields directly from ST_FIELD_INFO.
- For that purpose, and to be able to reuse the code in a convenient way, wrap create_tmp_table() into a class Create_tmp_table with approximately these methods:
{code:cpp}
class Create_tmp_table
{
public:
...
// The former beginning of {{create_tmp_table()}}
TABLE *start(THD *thd,
TMP_TABLE_PARAM *param,
const LEX_CSTRING *table_alias);
// The former loop of {{create_tmp_table()}} adding fields
bool add_fields(THD *thd, TABLE *table,
TMP_TABLE_PARAM *param, List<Item> &fields);
// A new code adding fields directly from ST_FIELD_INFO
bool add_schema_fields(THD *thd, TABLE *table,
TMP_TABLE_PARAM *param,
const ST_SCHEMA_TABLE &schema_table,
const MY_BITMAP &bitmap);
// The forder end of {{create_tmp_table()}}, after the loop.
bool finalize(THD *thd, TABLE *table, TMP_TABLE_PARAM *param,
bool do_not_open, bool keep_row_order);
};
{code}
- Remove method Item::create_field_for_schema()
- Remove class Item_return_date_time
- Remove class Item_blob
The code in create_schema_table() has switch's and if's testing MYSQL_TYPE_XXX.
This is not friendly to data type plugins.
Additionally, when schema tables are created in two steps:
- On the first step, Items are created from ST_FIELD_INFO
- On the second step, these Items create Fields
which is slow.
Let's do the following:
- Add a new method in Type_handler:
{code:sql}
virtual Field *make_schema_field(TABLE *table,
const Record_addr &addr,
const ST_FIELD_INFO &def,
bool show_field) const
{code}
- Change the logic to create Fields directly from ST_FIELD_INFO.
- For that purpose, and to be able to reuse the code in a convenient way, wrap create_tmp_table() into a class Create_tmp_table with approximately these methods:
{code:cpp}
class Create_tmp_table
{
public:
...
// The former beginning of {{create_tmp_table()}}
TABLE *start(THD *thd,
TMP_TABLE_PARAM *param,
const LEX_CSTRING *table_alias);
// The former loop of {{create_tmp_table()}} adding fields
bool add_fields(THD *thd, TABLE *table,
TMP_TABLE_PARAM *param, List<Item> &fields);
// A new code adding fields directly from ST_FIELD_INFO
bool add_schema_fields(THD *thd, TABLE *table,
TMP_TABLE_PARAM *param,
const ST_SCHEMA_TABLE &schema_table,
const MY_BITMAP &bitmap);
// The forder end of {{create_tmp_table()}}, after the loop.
bool finalize(THD *thd, TABLE *table, TMP_TABLE_PARAM *param,
bool do_not_open, bool keep_row_order);
};
{code}
- Remove method Item::create_field_for_schema()
- Remove class Item_return_date_time
- Remove class Item_blob
The code in create_schema_table() has switch's and if's testing MYSQL_TYPE_XXX.
This is not friendly to data type plugins.
Additionally, when schema tables are created in two steps:
- On the first step, Items are created from ST_FIELD_INFO
- On the second step, these Items create Fields
which is slow.
Let's do the following:
- Add a new method in Type_handler:
{code:sql}
virtual Field *make_schema_field(TABLE *table,
const Record_addr &addr,
const ST_FIELD_INFO &def,
bool show_field) const
{code}
- Change the logic to create Fields directly from ST_FIELD_INFO.
- For that purpose, and to be able to reuse the code in a convenient way, wrap create_tmp_table() into a class Create_tmp_table with approximately these methods:
{code:cpp}
class Create_tmp_table
{
public:
...
// The former beginning of create_tmp_table()
TABLE *start(THD *thd,
TMP_TABLE_PARAM *param,
const LEX_CSTRING *table_alias);
// The former loop of create_tmp_table(), adding fields into the table
bool add_fields(THD *thd, TABLE *table,
TMP_TABLE_PARAM *param, List<Item> &fields);
// A new code adding fields directly from ST_FIELD_INFO
bool add_schema_fields(THD *thd, TABLE *table,
TMP_TABLE_PARAM *param,
const ST_SCHEMA_TABLE &schema_table,
const MY_BITMAP &bitmap);
// The forder end of create_tmp_table(), after the loop adding fields.
bool finalize(THD *thd, TABLE *table, TMP_TABLE_PARAM *param,
bool do_not_open, bool keep_row_order);
};
{code}
- Remove method Item::create_field_for_schema()
- Remove class Item_return_date_time
- Remove class Item_blob
The old code made a really hard job on every INFORMATION_SCHEMA query:
converted every ST_FIELD_INFO into Item
then converted every new Item to Field
then put every new Field into List<Field>
and only after that called create_tmp_table() with the List<Field>
The new code just creates a table directly from the array of ST_FIELD_INFO without such heavy conversion
Unnecessary classes removed
These classes were used only in I_S table creation, in the ST_FIELD_INFO->Item->Field chain:
Item_return_date_time
Item_blob
After this change these classes were not needed any more, so they were removed.
Note, it should be also easy to remove class Item_return_int (in a separate change).
Creation of INFORMATION_SCHEMA tables is now faster
I_S tables are now created directly from an array of ST_FIELD_INFO, no such heavy conversion involved any more.
This example code runs 1% faster after the change:
mysql --socket=/tmp/mysql.sock -s --database=test << QEND
DELIMITER $$
CREATEORREPLACEPROCEDURE p1()
BEGIN
FOR i IN 1..1000000
DO
BEGIN
SELECT * FROM INFORMATION_SCHEMA.COLUMNS LIMIT 0;
END;
ENDFOR;
END;
$$
DELIMITER ;
QEND
time mysql --socket=/tmp/mysql.sock -s --database=test --execute="CALL p1()"
The code is now data type friendly
I_S columns of new data types now work out of the box, without a need of new wrapper classes like the former Item_blob, Item_return_date_time or Item_return_int. A new data type developer just needs to override Type_handler_xxx::create_schema_field(), which is one line method with a single new Field_xxx() statement.
User defined plugins are now able to have fields of their own data type in their pluggable INFORMATION_SCHEMA tables.
We'll be adding built-in SQL standard data types soon, such as TIMESTAMP WITH TIME ZONE, INTERVAL, so adding I_S columns of these types is also trivial.
It's now easy to extend creating of temporary tables
The new class Create_tmp_table now understands two input data formats:
List<Item>
ST_SCHEMA_TABLE
Adding new formats is now trivial and does not need heavy conversion like ST_FIELD_INFO->Item->Field. One just needs to add a proper add_fields() method.
Examples:
it's now trivial to create a temporary table directly from List<Item>. Currently we convert List<Item> into List<Field> in such cases. Direct table creation from List<Item> can make the code faster.
On ALTER, we convert every Field into Create_field. Such conversion is not really needed. We could create an altered table from a mixture of old Fields with new Create_fields, which would improve performance.
Alexander Barkov
added a comment - - edited Results of this change look good in many aspects.
Code change made summary
The old code made a really hard job on every INFORMATION_SCHEMA query:
converted every ST_FIELD_INFO into Item
then converted every new Item to Field
then put every new Field into List<Field>
and only after that called create_tmp_table() with the List<Field>
The new code just creates a table directly from the array of ST_FIELD_INFO without such heavy conversion
Unnecessary classes removed
These classes were used only in I_S table creation, in the ST_FIELD_INFO->Item->Field chain:
Item_return_date_time
Item_blob
After this change these classes were not needed any more, so they were removed.
Note, it should be also easy to remove class Item_return_int (in a separate change).
Creation of INFORMATION_SCHEMA tables is now faster
I_S tables are now created directly from an array of ST_FIELD_INFO, no such heavy conversion involved any more.
This example code runs 1% faster after the change:
mysql --socket=/tmp/mysql.sock -s --database=test << QEND
DELIMITER $$
CREATE OR REPLACE PROCEDURE p1()
BEGIN
FOR i IN 1..1000000
DO
BEGIN
SELECT * FROM INFORMATION_SCHEMA.COLUMNS LIMIT 0;
END ;
END FOR ;
END ;
$$
DELIMITER ;
QEND
time mysql --socket=/tmp/mysql.sock -s --database=test --execute="CALL p1()"
The code is now data type friendly
I_S columns of new data types now work out of the box, without a need of new wrapper classes like the former Item_blob, Item_return_date_time or Item_return_int. A new data type developer just needs to override Type_handler_xxx::create_schema_field(), which is one line method with a single new Field_xxx() statement.
User defined plugins are now able to have fields of their own data type in their pluggable INFORMATION_SCHEMA tables.
We'll be adding built-in SQL standard data types soon, such as TIMESTAMP WITH TIME ZONE, INTERVAL, so adding I_S columns of these types is also trivial.
It's now easy to extend creating of temporary tables
The new class Create_tmp_table now understands two input data formats:
List<Item>
ST_SCHEMA_TABLE
Adding new formats is now trivial and does not need heavy conversion like ST_FIELD_INFO->Item->Field. One just needs to add a proper add_fields() method.
Examples:
it's now trivial to create a temporary table directly from List<Item>. Currently we convert List<Item> into List<Field> in such cases. Direct table creation from List<Item> can make the code faster.
On ALTER, we convert every Field into Create_field. Such conversion is not really needed. We could create an altered table from a mixture of old Fields with new Create_fields, which would improve performance.
Results of this change look good in many aspects.
Code change made summary
The old code made a really hard job on every INFORMATION_SCHEMA query:
The new code just creates a table directly from the array of ST_FIELD_INFO without such heavy conversion
Unnecessary classes removed
These classes were used only in I_S table creation, in the ST_FIELD_INFO->Item->Field chain:
After this change these classes were not needed any more, so they were removed.
Note, it should be also easy to remove class Item_return_int (in a separate change).
Creation of INFORMATION_SCHEMA tables is now faster
I_S tables are now created directly from an array of ST_FIELD_INFO, no such heavy conversion involved any more.
This example code runs 1% faster after the change:
DELIMITER $$
BEGIN
DO
$$
DELIMITER ;
QEND
The code is now data type friendly
I_S columns of new data types now work out of the box, without a need of new wrapper classes like the former Item_blob, Item_return_date_time or Item_return_int. A new data type developer just needs to override Type_handler_xxx::create_schema_field(), which is one line method with a single new Field_xxx() statement.
It's now easy to extend creating of temporary tables
The new class Create_tmp_table now understands two input data formats:
Adding new formats is now trivial and does not need heavy conversion like ST_FIELD_INFO->Item->Field. One just needs to add a proper add_fields() method.
Examples: