Pass index to temporary table from regular table? - mysql

I am creating a temp table with a query like this:
CREATE TEMPORARY TABLE temp_table
SELECT * FROM regular_table
WHERE 1
But regular_table has FULLTEXT index on some of the fields. I try to do a FULLTEXT search on the new temporary table and I get an error telling me "Can't find FULLTEXT index matching the column list". So obviusly the index is not copying over to the new table. Is there a way to force this?
Thanks.

You could use CREATE TEMPORARY TABLE temp_table LIKE regular_table, but that will create all the indexes, so when you do INSERT INTO temp_table SELECT * FROM regular_table, the indexes will be rebuilt - which could be lengthy.
Or, you can create the table and add the index afterwards:
CREATE TEMPORARY TABLE temp_table
ALTER TABLE temp_table ADD FULLTEXT INDEX (foo,bar,baz)
INSERT INTO temp_table SELECT * FROM regular_table
but the index will be, again, updated on every insert.
Probably the most efficient way would be to create the temp table, insert all, build index afterwards:
CREATE TEMPORARY TABLE temp_table
ALTER TABLE temp_table ADD FULLTEXT INDEX (foo,bar,baz)
ALTER TABLE temp_table DISABLE KEYS
INSERT INTO temp_table SELECT * FROM regular_table
ALTER TABLE temp_table ENABLE KEYS
Again, you will have to wait for the index to build, except it will happen in one chunk, with the last ALTER statement.

A temporary table is exactly the same as any other table except that it will be dropped at the end of the session. The only way to have the same indexes (from within the database) is to create them on the table as you would any other table.
Now there is a bit of a hack. You can copy the physical files on disk to a new name and have a clone of the table which includes indexes but I'm assuming you're doing this within an app so that might not be very practical.

Related

How to convert a temporary table to permanent table in a single atomic operation?

How to convert a temporary table to a static table in a single atomic operation, while still being agnostic to the table structure but yet preserving it, in MySQL?
For a pre-created temporary table of:
CREATE TEMPORARY TABLE _tmp SELECT 0 AS Col1, 'text' AS Col2;
ALTER TABLE _tmp ADD UNIQUE INDEX (Col1, Col2);
Of course, one could always go:
CREATE TABLE permanent SELECT * FROM _tmp; -- 1
ALTER TABLE permanent ADD UNIQUE INDEX (Col1, Col2); -- 2
or, which I, for lack of a better solution, am using:
-- mostly agnostic to the structure unless for generated or auto-increment columns
CREATE TABLE permanent LIKE _tmp; -- 1
INSERT INTO permanent SELECT * FROM _tmp; -- 2
As shown above, right now I can only manage to do it with at least 2 (DDL + (DDL or DML)) statements.
Is there a way I can improve this to a single DDL? Perhaps a functionality that facilitates a feature combining LIKE & INSERT?
CREATE TABLE permanent
SELECT * FROM _tmp;
fiddle
or (if you need in unique key presence)
CREATE TABLE permanent ( UNIQUE KEY `Col1` (`Col1`,`Col2`) )
SELECT * FROM _tmp;
fiddle

how can i move all data of one table to another table

I need to transfer all data of one table to another dumping table.
My purpose is to get table ready for daily transaction and previous data should be moved to another table which stores every days data.
i need mysql syntax for this, thank you in advance for your support and help
You can try these queries:
This query will copy the data and structure, but the indexes are not included:
CREATE TABLE new_table SELECT * FROM old_table;
To copy everything, including database objects such as indexes, primary key constraint, foreign key constraints, triggers run these queries:
CREATE TABLE new_table LIKE old_table;
INSERT new_table SELECT * FROM old_table;
To insert data into an existing table, use this :
INSERT INTO table2 SELECT * FROM table1

ALTER TABLE with Large number of rows

I have an sales table with millions of records and I want to extend it with a new field. I know ALTER TABLE would certainly lead never ending process. Is there a faster way to do this?
Create table TEMP_TABLE WITH similer to your old table with additional column
INSERT INTO TAMP_TABLE (SELECT * FROM TABLE);
DROP TABLE OLD_TABLE;
RENAME TABLE TEMP_TABLE TO OLD_TABLE_NAME;

Optimize mySql for faster alter table add column

I have a table that has 170,002,225 rows with about 35 columns and two indexes. I want to add a column. The alter table command took about 10 hours. Neither the processor seemed busy during that time nor were there excessive IO waits. This is on a 4 way high performance box with tons of memory.
Is this the best I can do? Is there something I can look at to optimize the add column in tuning of the db?
I faced a very similar situation in the past and i improve the performance of the operation in this way :
Create a new table (using the structure of the current table) with the new column(s) included.
execute a INSERT INTO new_table (column1,..columnN) SELECT (column1,..columnN) FROM current_table;
rename the current table
rename the new table using the name of the current table.
ALTER TABLE in MySQL is actually going to create a new table with new schema, then re-INSERT all the data and delete the old table. You might save some time by creating the new table, loading the data and then renaming the table.
From "High Performance MySQL book" (the percona guys):
The usual trick for loading MyISAM table efficiently is to disable keys, load the data and renalbe the keys:
mysql> ALTER TABLE test.load_data DISABLE KEYS;
-- load data
mysql> ALTER TABLE test.load_data ENABLE KEYS;
Well, I would recommend using latest Percona MySQL builds plus since there is the following note in MySQL manual
In other cases, MySQL creates a
temporary table, even if the data
wouldn't strictly need to be copied.
For MyISAM tables, you can speed up
the index re-creation operation (which
is the slowest part of the alteration
process) by setting the
myisam_sort_buffer_size system
variable to a high value.
You can do ALTER TABLE DISABLE KEYS first, then add column and then ALTER TABLE ENABLE KEYS. I don't see anything can be done here.
BTW, can't you go MongoDB? It doesn't rebuild anything when you add column.
Maybe you can remove the index before alter the table because what is take most of the time to build is the index?
Combining some of the comments on the other answers, this was the solution that worked for me (MySQL 5.6):
create table mytablenew like mytable;
alter table mytablenew add column col4a varchar(12) not null after col4;
alter table mytablenew drop index index1, drop index index2,...drop index indexN;
insert into mytablenew (col1,col2,...colN) select col1,col2,...colN from mytable;
alter table mytablenew add index index1 (col1), add index index2 (col2),...add index indexN (colN);
rename table mytable to mytableold, mytablenew to mytable
On a 75M row table, dropping the indexes before the insert caused the query to complete in 24 minutes rather than 43 minutes.
Other answers/comments have insert into mytablenew (col1) select (col1) from mytable, but this results in ERROR 1241 (21000): Operand should contain 1 column(s) if you have the parenthesis in the select query.
Other answers/comments have insert into mytablenew select * from mytable;, but this results in ERROR 1136 (21S01): Column count doesn't match value count at row 1 if you've already added a column.

Create a temporary table in a SELECT statement without a separate CREATE TABLE

Is it possible to create a temporary (session only) table from a select statement without using a create table statement and specifying each column type? I know derived tables are capable of this, but those are super-temporary (statement-only) and I want to re-use.
It would save time if I did not have to write up a create table command and keep the column list and type list matched up.
CREATE TEMPORARY TABLE IF NOT EXISTS table2 AS (SELECT * FROM table1)
From the manual found at http://dev.mysql.com/doc/refman/5.7/en/create-table.html
You can use the TEMPORARY keyword when creating a table. A TEMPORARY table is visible only to the current session, and is dropped automatically when the session is closed. This means that two different sessions can use the same temporary table name without conflicting with each other or with an existing non-TEMPORARY table of the same name. (The existing table is hidden until the temporary table is dropped.) To create temporary tables, you must have the CREATE TEMPORARY TABLES privilege.
In addition to psparrow's answer if you need to add an index to your temporary table do:
CREATE TEMPORARY TABLE IF NOT EXISTS
temp_table ( INDEX(col_2) )
ENGINE=MyISAM
AS (
SELECT col_1, coll_2, coll_3
FROM mytable
)
It also works with PRIMARY KEY
Use this syntax:
CREATE TEMPORARY TABLE t1 (select * from t2);
Engine must be before select:
CREATE TEMPORARY TABLE temp1 ENGINE=MEMORY
as (select * from table1)
ENGINE=MEMORY is not supported when table contains BLOB/TEXT columns
As I understand it, a SELECT statement will work on the temporary table if you're using it in something like phpMyAdmin, but following that SELECT, the temporary table will be gone. This means set up exactly what you want to do with it first, and don't view any results till your 'action' statements that change the data (DELETE, UPDATE) are complete.