2009-09-12 3 views
3

매우 강력한 하드웨어 (8 Xeon 코어가있는 HP DL360, 8Gb RAM 및 RAID10)에서 적당한 부하 (200-300 QPS)로 MySQL 서버를 실행합니다. 모든 테이블은 무효이며 활성 데이터 셋은 할당 된 innodb_buffer_pool_size 내에 들어갑니다.CREATE TABLE AS SELECT 죽이는 MySQL

우리의 데이터베이스는 표준화되어 있으며 우리가 데이터 세트를 평평하게 만들기 위해 구체화 된 뷰를 사용하는 조인 횟수를 줄입니다. 하루에 몇 번씩 데이터가 일괄 적으로 추가되므로 MV :는 복잡한 트리거를 사용하여 동적으로 업데이트되는 대신 CREATE TABLE AS SELECT을 사용하여 재생성됩니다.

이러한 CREATE 쿼리가 실행되는 동안 (각각 5 초에서 50 초가 소요됨) 서버와 관련이없는 다른 쿼리는 CREATE 쿼리 뒤에 대기열로 연결되어 응답하지 않는 데이터베이스로 이어지는 경우가 있습니다. (재) 생성 MV으로

: S 우리는 같은 것을 사용

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 completly 과부하 우리 서버 및 어떻게 방지 할 수 있습니까?

감사합니다.

+3

SQL Server에서 SELECT ... INTO (CREATE TABLE ... SELECT와 동일한 개념)를 수행하면 전체 원본 테이블이 잠기므로 다른 쿼리가 대기열에 들어갑니다. 이는 의도적으로 설계된 동작입니다. MySQL에도 비슷한 동작이있을 수 있습니다. MySQL을 잘 모르기 때문에 적절한 대답을하지 않았습니다. –

+0

다음과 같이 보입니다. http://www.mysqlperformanceblog.com/2006/07/12/insert-into-select-performance-with-innodb-tables/. 나는 월요일에 약간의 시험을 할 것이다. – Paso

+0

의견을 정답으로 사용하려면 답변으로 다시 게시하십시오. – Paso

답변

1

이것이 원인 일 수 있습니까?

주 : TEMPORARY 키워드를 사용하지 않으면 DROP TABLE이 현재 활성 트랜잭션을 자동으로 커밋합니다.

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

+0

감사합니다. 트랜잭션을 CREATE TABLE 및 ALTER TABLE 문만 포함하도록 변경하겠습니다. 그러나 나는 이것이 내 문제의 근원이되는 것을 어떻게 볼 수 없는가? CREATE TABLE 문만으로 서버에 과부하가 걸리고 하나의 명령문만으로도 트랜잭션 성능이 현저하게 향상되지 않아야한다. – Paso