I have a working theory (LaForge would say to Capt Picard)...
Since you are using MySQL 5.1, you have access to the table INFORMATION_SCHEMA.PROCESSLIST.
You also have access to the ID of the current process the trigger is running on. The function to get that process ID is CONNECTION_ID.
You could try to fish out the query like this:
SELECT info FROM INFORMATION_SCHEMA.PROCESSLIST WHERE id = CONNECTION_ID();
Keep in mind that the info
is LONGTEXT:
mysql> show create table information_schema.processlist\G
*************************** 1. row ***************************
Table: PROCESSLIST
Create Table: CREATE TEMPORARY TABLE `PROCESSLIST` (
`ID` bigint(4) NOT NULL DEFAULT '0',
`USER` varchar(16) NOT NULL DEFAULT '',
`HOST` varchar(64) NOT NULL DEFAULT '',
`DB` varchar(64) DEFAULT NULL,
`COMMAND` varchar(16) NOT NULL DEFAULT '',
`TIME` int(7) NOT NULL DEFAULT '0',
`STATE` varchar(64) DEFAULT NULL,
`INFO` longtext
) ENGINE=MyISAM DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
Within the trigger, you could use a local variable to hold the query
DECLARE original_query VARCHAR(1024);
and then capture the query
SELECT info INTO original_query FROM INFORMATION_SCHEMA.PROCESSLIST WHERE id = CONNECTION_ID();
Give it a Try !!!
If it works, then
Make it so (Capt Picard would quip back to LaForge)
According to MySQL Certification Guide :
The OPTIMIZE TABLE statement cleans up a MyISAM table by defragmenting
it. This involves reclaiming unused space resulting from deletes and
updates, and coalescing records that have become split and stored
non-contiguously. OPTIMIZE TABLE also sorts the index pages if they
are out of order and updates the index statistics
Also works for InnoDB tables, but maps to ALTER TABLE, which rebuilds
the table. This updates index statistics and frees space in the
clustered index.
So In Case of InnoDB :
Innodb is ACID compliant, the optimize table simply copies all records into a new table
- If the index pages are not sorted, sort them,
- If the table's statistics are not up to date (and the repair could not be accomplished by sorting the index), update them.
- If the table has deleted or split rows, repair the table.
And if you try to kill it when it's running you will not loose any records.
Additionally, case of InnoDB with innodb_defragment=1
, there will be no ROLLBACK required, as in this case OPTIMIZE TABLE
is incremental.
Best Answer
First thing to know is what
ANALYZE TABLE
does.For a MyISAM table
mydb.mytable
,ANALYZE TABLE
traverses all the indexes in themytable.MYI
file, reads all BTREE pages, computes statistics, and stores in them in the information_schema, specificallySTATISTICS
. You can see it when you run one of the following:SHOW INDEXES FROM mydb.mytable;
SELECT * FROM information_schema.statistics WHERE table_schema='mydb' AND table_name='mytable';
ANALYZE TABLE
is a read-only operation and does issue a table-wide read lock.ANSWER TO YOUR QUESTION
Yes, you can kill
ANALYZE TABLE
and wait briefly for the read lock to be released. However, there is a significant penalty. Because the index statistics will not be completely computed, the MySQL Query Optimizer will take rather bad guesses at generating EXPLAIN plans of queries against that table.SUGGESTIONS
SUGGESTION #1 : Delay
ANALYZE TABLE
If you want to run
OPTIMIZE TABLE mydb.mytable
without doing theANALYZE TABLE
operation, do the following:This will rename the table, perform the defragmentation, and rename it back.
You could do it in one line as well
If you want to run
ANALYZE TABLE
later on, set up a cron job to run it in every midnight or perhaps once a week. You will have to do this inevitably if you expect queries against your table to perform well after an optimization.SUGGESTION #2 : Change the MyISAM table to InnoDB
During the generation of an EXPLAIN plan, InnoDB will perform reads against the index pages of a table by traversing 2-3 levels of nonleaf nodes and literally approximate (or really guess) the cardinality of all column levels. You can tell this is happening to an InnoDB table when you run
SHOW INDEXES FROM mydb.mytable;
because the cardinality changes with each run.In light of this, you can simply run
and that's it. Even if you ran
ANALYZE TABLE
on an InnoDB table, the statistics can get rather stale. By default,innodb_stats_on_metadata
is already disabled in MySQL 5.6. If you have MySQL 5.5 and prior, you can disable the update of the statistics by doing this:You will still have to bite the bullet and run
ANALYZE TABLE
sometime downstream if the InnoDB table experiences high INSERTs, UPDATEs, and DELETEs. Otherwise, the MySQL Query Optimizer will take bad guesses at EXPLAIN plans.