CREATE TABLE AS SELECT杀死MySQL

时间:2009-09-12 10:13:43

标签: sql mysql transactions materialized-views

我们在相当强大的硬件(具有8个Xeon核心的HP DL360,8Gb RAM和RAID10)上运行具有中等负载(200-300 QPS)的MySQL服务器。所有表都是innodb,活动数据集适合分配的innodb_buffer_pool_size

我们的数据库已规范化,为了减少连接数,我们使用物化视图来展平数据集。由于数据每天分批添加几次,因此使用CREATE TABLE AS SELECT重新生成MV:而不是使用复杂触发器动态更新。

问题在于,有时在运行这些CREATE查询时(每个查询需要5到50秒),对服务器的其他无关查询似乎排在CREATE查询后面,导致数据库没有响应。

要(重新)生成MV:我们使用这样的东西:

BEGIN TRANSACTION;
DROP TABLE IF EXISTS TableName_TMP;
CREATE TABLE TableName_TMP ENGINE=INNODB CHARACTER SET utf8 COLLATE utf8_swedish_ci AS 
    SELECT about100columns, and10Expressions 
    FROM Table1 
    JOIN Table2 ON Table1.fk = Table2.pk 
    /* join up to 13 other tables */
    WHERE ((removed IS NULL OR removed = 0)) 
    ORDER BY created DESC, id ASC;
ALTER TABLE TableName_TMP ADD PRIMARY KEY(id), INDEX(created);
DROP TABLE IF EXISTS TableName;
ALTER TABLE TableName_TMP RENAME TO TableName;
COMMIT;

SELECT的EXPLAIN产生类似的东西:

+----+-------------+------------------+-------------+---------------+------------+---------+------------------------------+-------+-----------------------------+
| id | select_type | table            | type        | possible_keys | key        | key_len | ref                          | rows  | Extra                       |
+----+-------------+------------------+-------------+---------------+------------+---------+    ------------------------------+-------+-----------------------------+
|  1 | SIMPLE      | Table1           | ref_or_null | removed       | removed    | 5       | const                        | 76093 | Using where; Using filesort | 
|  1 | SIMPLE      | Table2           | eq_ref      | PRIMARY       | PRIMARY    | 4       | Table1.fk1                   |     1 |                             | 
|  1 | SIMPLE      | Table3           | eq_ref      | PRIMARY       | PRIMARY    | 4       | Table1.fk2                   |     1 |                             | 
/* More of the same */
|  1 | SIMPLE      | TableN           | eq_ref      | PRIMARY       | PRIMARY    | 4        | TableM.fk                    |     1 | Using index                 | 
|  1 | SIMPLE      | TableX           | eq_ref      | PRIMARY       | PRIMARY    | 4       | TableY.fk                    |     1 |                             | 
/* More of the same */    
+----+-------------+------------------+-------------+---------------+------------+---------+------------------------------+-------+-----------------------------+

任何想法为什么CREATE TABLE AS完全超载我们的服务器以及如何阻止它?

此致

2 个答案:

答案 0 :(得分:3)

我们通过http://www.mysqlperformanceblog.com/2006/07/12/insert-into-select-performance-with-innodb-tables/切换到SELECT INTO和LOAD DATA INFILE解决了这个问题。非常感谢Randolph Potter让我们朝着正确的方向前进。

答案 1 :(得分:1)

这可能是原因吗?

注意:除非使用TEMPORARY关键字,否则DROP TABLE会自动提交当前活动事务。

http://dev.mysql.com/doc/refman/5.1/en/drop-table.html