mirror of
https://github.com/MariaDB/server.git
synced 2026-05-15 19:37:16 +02:00
use bulk insert and repair by sort for unique keys in
Aria and MyISAM in create_internal_tmp_table_from_heap() (safe, as duplicates are impossible). This gives a HUGE speed boost! sql/opt_subselect.cc: Fixed problem with wrong recinfo in create_duplicate_weedout_tmp_tabl() Tagged the table with 'no_rows' so that when we create the table on disk, we only store the index data. This gave us a major speedup! sql/sql_select.cc: create_tmp_table_from_heap() now uses bulk_insert + repair_by_sort when creating Aria/MyISAM tables from HEAP tables. This gives a HUGE speed boost! storage/maria/ha_maria.cc: Extended bulk_insert() to recreate UNIQUE keys for internal temporary tables storage/maria/ma_open.c: Initialize m_info->lock.type properly for temporarly tables (needed for start_bulk_insert()) storage/maria/ma_write.c: Don't check uniques that are disabled storage/myisam/ha_myisam.cc: Extended bulk_insert() to recreate UNIQUE keys for internal temporary tables.
This commit is contained in:
parent
6554977fe5
commit
418df96d51
7 changed files with 53 additions and 24 deletions
|
|
@ -2786,12 +2786,15 @@ TABLE *create_duplicate_weedout_tmp_table(THD *thd,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (thd->is_fatal_error) // If end of memory
|
if (thd->is_fatal_error) // If end of memory
|
||||||
goto err;
|
goto err;
|
||||||
share->db_record_offset= 1;
|
share->db_record_offset= 1;
|
||||||
|
table->no_rows= 1; // We don't need the data
|
||||||
|
|
||||||
|
// recinfo must point after last field
|
||||||
|
recinfo++;
|
||||||
if (share->db_type() == TMP_ENGINE_HTON)
|
if (share->db_type() == TMP_ENGINE_HTON)
|
||||||
{
|
{
|
||||||
recinfo++;
|
|
||||||
if (create_internal_tmp_table(table, keyinfo, start_recinfo, &recinfo, 0))
|
if (create_internal_tmp_table(table, keyinfo, start_recinfo, &recinfo, 0))
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12796,6 +12796,7 @@ create_internal_tmp_table_from_heap2(THD *thd, TABLE *table,
|
||||||
save_proc_info=thd->proc_info;
|
save_proc_info=thd->proc_info;
|
||||||
thd_proc_info(thd, proc_info);
|
thd_proc_info(thd, proc_info);
|
||||||
|
|
||||||
|
new_table.no_rows= table->no_rows;
|
||||||
if (create_internal_tmp_table(&new_table, table->key_info, start_recinfo,
|
if (create_internal_tmp_table(&new_table, table->key_info, start_recinfo,
|
||||||
recinfo, thd->lex->select_lex.options |
|
recinfo, thd->lex->select_lex.options |
|
||||||
thd->options))
|
thd->options))
|
||||||
|
|
@ -12807,24 +12808,15 @@ create_internal_tmp_table_from_heap2(THD *thd, TABLE *table,
|
||||||
table->file->ha_index_or_rnd_end();
|
table->file->ha_index_or_rnd_end();
|
||||||
if (table->file->ha_rnd_init_with_error(1))
|
if (table->file->ha_rnd_init_with_error(1))
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
if (table->no_rows)
|
if (new_table.no_rows)
|
||||||
{
|
|
||||||
new_table.file->extra(HA_EXTRA_NO_ROWS);
|
new_table.file->extra(HA_EXTRA_NO_ROWS);
|
||||||
new_table.no_rows=1;
|
else
|
||||||
|
{
|
||||||
|
/* update table->file->stats.records */
|
||||||
|
table->file->info(HA_STATUS_VARIABLE);
|
||||||
|
new_table.file->ha_start_bulk_insert(table->file->stats.records);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef TO_BE_DONE_LATER_IN_4_1
|
|
||||||
/*
|
|
||||||
To use start_bulk_insert() (which is new in 4.1) we need to find
|
|
||||||
all places where a corresponding end_bulk_insert() should be put.
|
|
||||||
*/
|
|
||||||
table->file->info(HA_STATUS_VARIABLE); /* update table->file->stats.records */
|
|
||||||
new_table.file->ha_start_bulk_insert(table->file->stats.records);
|
|
||||||
#else
|
|
||||||
/* HA_EXTRA_WRITE_CACHE can stay until close, no need to disable it */
|
|
||||||
new_table.file->extra(HA_EXTRA_WRITE_CACHE);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
copy all old rows from heap table to MyISAM table
|
copy all old rows from heap table to MyISAM table
|
||||||
This is the only code that uses record[1] to read/write but this
|
This is the only code that uses record[1] to read/write but this
|
||||||
|
|
@ -12838,6 +12830,8 @@ create_internal_tmp_table_from_heap2(THD *thd, TABLE *table,
|
||||||
if (write_err)
|
if (write_err)
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
if (!new_table.no_rows && new_table.file->ha_end_bulk_insert())
|
||||||
|
goto err;
|
||||||
/* copy row that filled HEAP table */
|
/* copy row that filled HEAP table */
|
||||||
if ((write_err=new_table.file->ha_write_tmp_row(table->record[0])))
|
if ((write_err=new_table.file->ha_write_tmp_row(table->record[0])))
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1998,7 +1998,14 @@ void ha_maria::start_bulk_insert(ha_rows rows)
|
||||||
@todo for a single-row INSERT SELECT, we will go into repair, which
|
@todo for a single-row INSERT SELECT, we will go into repair, which
|
||||||
is more costly (flushes, syncs) than a row write.
|
is more costly (flushes, syncs) than a row write.
|
||||||
*/
|
*/
|
||||||
maria_disable_non_unique_index(file, rows);
|
if (file->open_flags & HA_OPEN_INTERNAL_TABLE)
|
||||||
|
{
|
||||||
|
/* Internal table; If we get a duplicate something is very wrong */
|
||||||
|
file->update|= HA_STATE_CHANGED;
|
||||||
|
maria_clear_all_keys_active(file->s->state.key_map);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
maria_disable_non_unique_index(file, rows);
|
||||||
if (share->now_transactional)
|
if (share->now_transactional)
|
||||||
{
|
{
|
||||||
bulk_insert_single_undo= BULK_INSERT_SINGLE_UNDO_AND_NO_REPAIR;
|
bulk_insert_single_undo= BULK_INSERT_SINGLE_UNDO_AND_NO_REPAIR;
|
||||||
|
|
|
||||||
|
|
@ -203,6 +203,9 @@ static MARIA_HA *maria_clone_internal(MARIA_SHARE *share, const char *name,
|
||||||
#ifdef THREAD
|
#ifdef THREAD
|
||||||
thr_lock_data_init(&share->lock,&m_info->lock,(void*) m_info);
|
thr_lock_data_init(&share->lock,&m_info->lock,(void*) m_info);
|
||||||
#endif
|
#endif
|
||||||
|
if (share->options & HA_OPTION_TMP_TABLE)
|
||||||
|
m_info->lock.type= TL_WRITE;
|
||||||
|
|
||||||
m_info->open_list.data=(void*) m_info;
|
m_info->open_list.data=(void*) m_info;
|
||||||
maria_open_list=list_add(maria_open_list,&m_info->open_list);
|
maria_open_list=list_add(maria_open_list,&m_info->open_list);
|
||||||
|
|
||||||
|
|
@ -935,6 +938,8 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
|
||||||
share->state.changed));
|
share->state.changed));
|
||||||
|
|
||||||
pthread_mutex_unlock(&THR_LOCK_maria);
|
pthread_mutex_unlock(&THR_LOCK_maria);
|
||||||
|
|
||||||
|
m_info->open_flags= open_flags;
|
||||||
DBUG_RETURN(m_info);
|
DBUG_RETURN(m_info);
|
||||||
|
|
||||||
err:
|
err:
|
||||||
|
|
|
||||||
|
|
@ -124,12 +124,23 @@ int maria_write(MARIA_HA *info, uchar *record)
|
||||||
goto err2;
|
goto err2;
|
||||||
|
|
||||||
/* Calculate and check all unique constraints */
|
/* Calculate and check all unique constraints */
|
||||||
for (i=0 ; i < share->state.header.uniques ; i++)
|
|
||||||
|
if (share->state.header.uniques)
|
||||||
{
|
{
|
||||||
if (_ma_check_unique(info,share->uniqueinfo+i,record,
|
for (i=0 ; i < share->state.header.uniques ; i++)
|
||||||
_ma_unique_hash(share->uniqueinfo+i,record),
|
{
|
||||||
HA_OFFSET_ERROR))
|
MARIA_UNIQUEDEF *def= share->uniqueinfo + i;
|
||||||
goto err2;
|
ha_checksum unique_hash= _ma_unique_hash(share->uniqueinfo+i,record);
|
||||||
|
if (maria_is_key_active(share->state.key_map, def->key))
|
||||||
|
{
|
||||||
|
if (_ma_check_unique(info, def, record,
|
||||||
|
unique_hash, HA_OFFSET_ERROR))
|
||||||
|
goto err2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
maria_unique_store(record+ share->keyinfo[def->key].seg->start,
|
||||||
|
unique_hash);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Ensure we don't try to restore auto_increment if it doesn't change */
|
/* Ensure we don't try to restore auto_increment if it doesn't change */
|
||||||
|
|
|
||||||
|
|
@ -550,6 +550,7 @@ struct st_maria_handler
|
||||||
ulong row_base_length; /* Length of row header */
|
ulong row_base_length; /* Length of row header */
|
||||||
uint row_flag; /* Flag to store in row header */
|
uint row_flag; /* Flag to store in row header */
|
||||||
uint opt_flag; /* Optim. for space/speed */
|
uint opt_flag; /* Optim. for space/speed */
|
||||||
|
uint open_flags; /* Flags used in open() */
|
||||||
uint update; /* If file changed since open */
|
uint update; /* If file changed since open */
|
||||||
int lastinx; /* Last used index */
|
int lastinx; /* Last used index */
|
||||||
uint last_rkey_length; /* Last length in maria_rkey() */
|
uint last_rkey_length; /* Last length in maria_rkey() */
|
||||||
|
|
|
||||||
|
|
@ -1596,7 +1596,15 @@ void ha_myisam::start_bulk_insert(ha_rows rows)
|
||||||
*/
|
*/
|
||||||
if (file->state->records == 0 && can_enable_indexes &&
|
if (file->state->records == 0 && can_enable_indexes &&
|
||||||
(!rows || rows >= MI_MIN_ROWS_TO_DISABLE_INDEXES))
|
(!rows || rows >= MI_MIN_ROWS_TO_DISABLE_INDEXES))
|
||||||
mi_disable_non_unique_index(file,rows);
|
{
|
||||||
|
if (file->open_flag & HA_OPEN_INTERNAL_TABLE)
|
||||||
|
{
|
||||||
|
file->update|= HA_STATE_CHANGED;
|
||||||
|
mi_clear_all_keys_active(file->s->state.key_map);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mi_disable_non_unique_index(file,rows);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
if (!file->bulk_insert &&
|
if (!file->bulk_insert &&
|
||||||
(!rows || rows >= MI_MIN_ROWS_TO_USE_BULK_INSERT))
|
(!rows || rows >= MI_MIN_ROWS_TO_USE_BULK_INSERT))
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue