CREATE TABLE AS SELECT убивает MySQL - PullRequest
       10

CREATE TABLE AS SELECT убивает MySQL

3 голосов
/ 12 сентября 2009

Мы запускаем сервер MySQL с умеренной нагрузкой (200-300 QPS) на довольно мощном оборудовании (HP DL360 с 8 ядрами Xeon, 8 ГБ ОЗУ и RAID10). Все таблицы являются innodb, и активный набор данных вписывается в выделенный innodb_buffer_pool_size.

Наша база данных нормализована, и для уменьшения количества объединений мы используем материализованные представления, чтобы сгладить набор данных. Поскольку данные добавляются партиями несколько раз в день, MV: s регенерируются с использованием CREATE TABLE AS SELECT вместо динамического обновления с использованием сложных триггеров.

Проблема в том, что иногда при выполнении этих 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;

ОБЪЯСНЕНИЕ ВЫБОРА производит что-то вроде:

+----+-------------+------------------+-------------+---------------+------------+---------+------------------------------+-------+-----------------------------+
| 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 ]

3 голосов
/ 25 февраля 2010

Мы решили это, переключившись на SELECT INTO и LOAD DATA INFILE, как на http://www.mysqlperformanceblog.com/2006/07/12/insert-into-select-performance-with-innodb-tables/. Большое спасибо Рэндольфу Поттеру за то, что он направил нас в правильном направлении.

1 голос
/ 12 сентября 2009

Может ли это быть причиной?

Примечание. DROP TABLE автоматически фиксирует текущую активную транзакцию, если только вы не используете ключевое слово TEMPORARY.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...