The code behind pushdown select performs the following operations during Pushdown_select::init():
That needs a lot of allocation and initialization:
- TABLE - 976 bytes
- TABLE_SHARE - 1424 bytes
- An array of Fields inside TABLE - at least 208 bytes each Field
- An array of Item_field, one Item for every Field - at least 320 bytes each
In fact we don't need so many structures to perform a pushed select.
Instead, we could allocate an array of literal Items, e.g. Item_int, Item_real, Item_string, Item_time_literal, etc, depending on the data type.
The attached patch demonstrates this approach for a SELECT consisting of a single column, for the FederatedX storage engine, assuming a column of an integer data type.
Note, the patch was tested only for the case when the results are sent to the client (e.g. not to another table in INSERT..SELECT or anywhere else, this needs some more coding).
Remote database DDL:
Local database DDL:
Local database query:
Notice, the new concept prototype code returns a correct result set, the same to the non-pushed query.
As the next step, we could also get rid of literal Items and replace them to:
- an array of generic value containers (either in ValueBuffer or in NativeBuffer), or just an iterator, so we need just one value container
- new virtual methods in Type_handler to populate a value container
- new virtual methods in Type_handler to send a value containers to the result sink
- This array can be created during the first pushed SELECT and later reused by consequent pushed SELECTs.
- Protocol::send_result_set_row() already uses ValueBuffer, so this code can be shared with pushed SELECTs.
- TODO: think what other benefits (over the array of literal Items) we can gain with this approach