我们在相当强大的硬件上(HP DL360,8个Xeon核心,8GB RAM和RAID10)运行一个MySQL服务器,负载适中(200-300 QPS)。所有表都是InnoDB,并且活动数据集适合于分配的innodb_buffer_pool_size。
我们的数据库已规范化,为了减少连接次数,我们使用物化视图来展开数据集。由于数据每天批量添加几次,因此使用CREATE TABLE AS SELECT重新生成MV:而不是使用复杂触发器动态更新它们。
问题在于,有时在运行这些CREATE查询(每个查询需要5到50秒不等)时,其他与服务器无关的查询似乎被排队在CREATE查询后面,导致数据库无响应。
为了重新生成MV:,我们使用类似以下的方法:
我们的数据库已规范化,为了减少连接次数,我们使用物化视图来展开数据集。由于数据每天批量添加几次,因此使用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
会完全超载我们的服务器,我该如何防止呢?
谢谢!