2012-05-10 3 views
0

mongodb 및 mysql에서 데이터를 모두 보았습니다. 행에 필드 list_id가 있으면 하나의 list_id가있는 매우 많은 행이있을 수 있습니다. mongdb에서 여러 문서를 삭제하는 것이 mysql에서 여러 행을 삭제하는 것보다 훨씬 빠릅니다. 나는 mysql에서 innodb 엔진을 사용한다. Mysql과 mongdb가 동일한 서버에 있습니다. 예를 들어 ,mongdb에서 여러 문서를 삭제하는 것이 mysql에서 여러 행을 삭제하는 것보다 훨씬 빠릅니다.

DELETE FROM contacts WHERE list_id = 100 

내가 PHP에서 드라이버에 대한 안전 모드를 사용

return self::remove(array('LISTID' => $listId), array('safe' => true)); 

보다 훨씬 느린, 그래서 모든 데이터가 삭제 될 때까지 기다려야합니다. 여기

는 MongoDB의 수집에 대한 정보입니다 : 예를 들어

"count" : 23456989, 
     "size" : 4391452160, 
     "avgObjSize" : 187.21295218239646, 
     "storageSize" : 5727051776, 
     "numExtents" : 32, 
     "nindexes" : 2, 
     "lastExtentSize" : 961069056, 
     "paddingFactor" : 1.0099999999950207, 
     "flags" : 1, 
     "totalIndexSize" : 2983806672, 
     "indexSizes" : { 
       "_id_" : 787504144, 
       "LISTID_1_EMAIL_1" : 2196302528 
     }, 
     "ok" : 1 
} 

, 그것은 MySQL의에서, 약 30 배 빠른 속도의 MongoDB를에, 조건을 만족이 100K 행은 모든 100K 행을 삭제하는 데 약 99 초가 소요 경우 그 이 조건을 충족 시키십시오.

색인은 mysql과 mongodb에서 모두 사용됩니다.

EXPLAIN SELECT * 
FROM `subscribers` 
WHERE list_id =118 

id select_type  table type possible_keys key  key_len  ref  rows Extra 
1 SIMPLE subscribers  ref  FK_list_id FK_list_id 4 const 1  

지금, 나는 덩어리로 데이터를 삭제, 큐에 데이터를 입력하고 그것을 배경을 온라인으로이 작업을하지 않습니다.

하지만 20-30 번 정도의 차이가 나는 이유는 무엇일까? mongodb에서 삭제 작업이 훨씬 빠르다. mongodb에서는이 작업이 원적이지 않으므로?

이것은 무엇 100K 행을 삭제하는

SET PROFILING = 1; 
DELETE FROM subscribers WHERE list_id = 118; 
SHOW PROFILE FOR QUERY 1; 

표시 : 번호 및 세부 사항없이

starting 0.000052 
checking permissions 0.000000 
Opening tables 0.000000 
System lock  0.000000 
init 0.000000 
updating 84.382015 
end  0.000006 
Waiting for query cache lock 0.000002 
end  0.000006 
query end 0.035284 
closing tables 0.000021 
freeing items 0.000040 
logging slow query 0.000001 
logging slow query 0.000002 
cleaning up  0.000002 
+0

무의미한 질문을 시도 WHERE

UPDATE 연락처 SET는 = 사실 삭제. 트랜잭션 무결성, 외래 키 다루기 등이 MongoDB보다 비싸기 때문에 RDBMS에서 물건을 제거하는 것이 더 비쌉니다. 특히 MongoDB는 화재와 잊기 때문에 작업이 끝나지 않은 것을 알 수 없습니다. –

+0

mongodb 안전 모드가 사용되므로 삭제할 때까지 기다려야합니다. – Oleg

+0

당신이 사용하고있는 엔진 (innodb, myisam 또는 다른 것)을 말하지 않았기 때문에 정확히 말하기는 어렵지만, Mongo는 fsync를 지연시키지 않아 속도가 빨라진다. 가끔). –

답변

1

무의미한 질문입니다. 트랜잭션 무결성, 외래 키 다루기 등이 MongoDB보다 비싸기 때문에 RDBMS에서 물건을 제거하는 것이 더 비쌉니다. 특히 MongoDB는 불이 나고 잊어 버리고 작업이 끝나지 않을 때 알 수 없습니다.

+0

mongodb 안전 모드가 사용되므로 삭제할 때까지 기다려야합니다. – Oleg

+0

원하는 전화 번호와 세부 정보는 무엇입니까? – Oleg

+0

나는 2 대의 차를 가지고있다. 자동차 A는 자동차 B보다 30 배 빠릅니다. 원하는 숫자는 무엇입니까? –

0

병목 현상이 쿼리인지 확인할 수 있습니다. 얼마나 걸리나요? 이 빨리 경우

SELECT FROM contacts WHERE list_id = 100 

다음 몇 가지 일반적인 방법은

  • 가 rows_affected만큼 덩어리 삭제 될 것은 연락처에서> 0

    삭제되는 경우 list_id로 = 100 LIMIT 1000

  • 인덱스를 삭제하고 (list_id 제외), 삭제하고 인덱스를 다시 작성하십시오. MySql은 삭제할 때마다 색인을 다시 작성해야합니다.

  • 논리 삭제 열을 추가하십시오. 귀하의 질문에 존중하십시오. 때때로 오래된 레코드를 삭제하는 cron 작업을 실행하십시오.list_id로 = 100

  • 숫자와 세부 사항이없는 다른 스토리지 엔진 (의 MyISAM)

+0

그 필드는 인덱스라고했는데, SELECT FROM where list_id = 100은 빠릅니다. – Oleg

+0

내 질문에 나는 지금이 작업을 온라인으로 만들지 않는다고 썼다. 나는 데이터를 대기열에 넣고 배경 작업을 수행한다. 청크로 데이터를 삭제하고 스크립트는 cron으로 실행한다. 문제는 mongodb와 mysql에서 삭제되는 시간이 너무 다른 이유입니다. 트랜잭션이 필요하기 때문에 MyISAM을 사용할 수 없으며 데이터를 쿼리하기 위해 생성되는 모든 인덱스가 필요합니다. – Oleg

+0

InnoDB는 행을 삽입/갱신/삭제할 때마다 인덱스를 재 구축해야한다. 삽입의 경우 MySQL은 대량 삽입에 대한이 문제를 해결하는 'INSERT DELAYED ...'명령을 지원합니다. 삭제와 같은 것은 없습니다. InnoDB가 트랜잭션을 사용하기 때문에 쿼리가 레코드 99,999 (100,00 0)에 실패하고 InnoDB가 전체 트랜잭션을 롤백해야하는 경우가 발생할 수 있습니다. 이는 커다란 작업입니다 (연락처에 contact_numbers에 대한 FK-Relation이있는 경우'on delete cascade '롤백하는 것이 훨씬 더 많습니다. 한번에 1000에서 10,000 행 사이를 지우는 것이 좋습니다. –