MySQL은 수십억 행에 대해 합리적으로 쿼리를 수행 할 수 있습니까?


283

질량 분석계의 스캔을 MySQL 데이터베이스에 저장하려고 계획 중이며이 양의 데이터를 저장하고 분석하는 것이 원격으로 가능한지 알고 싶습니다. 성능에 따라 환경에 따라 크게 차이가 나는 것을 알고 있지만 대략적인 규모의 쿼리를 찾고 있습니다. 쿼리에 5 일 또는 5 밀리 초가 소요됩니까?

입력 형식

각 입력 파일에는 분광계의 단일 실행이 포함됩니다. 각 실행은 일련의 스캔으로 구성되며 각 스캔에는 순서가 지정된 데이터 포인트 배열이 있습니다. 메타 데이터는 약간 있지만 파일의 대부분은 32 비트 또는 64 비트 정수 또는 부동 소수점 배열로 구성됩니다.

호스트 시스템

| ---------------- + ------------------------------- |
| OS | Windows 2008 64 비트 |
| MySQL 버전 | 5.5.24 (x86_64) |
| CPU | 2x Xeon E5420 (총 8 코어) |
| 램 | 8GB |
| SSD 파일 시스템 | 500GiB |
| HDD RAID | 12TiB |
| ---------------- + ------------------------------- |

무시할만한 프로세서 시간을 사용하여 서버에서 실행되는 다른 서비스가 있습니다.

파일 통계

| ------------------ + -------------- |
| 파일 수 | ~ 16,000 |
| 총 크기 | 1.3TiB |
| 최소 크기 | 0 바이트 |
| 최대 크기 | 12GiB |
| 평균 | 800 MiB |
| 중앙값 | 500 MiB |
| 총 데이터 포인트 | ~ 2,000 억 |
| ------------------ + -------------- |

총 데이터 포인트 수는 매우 대략적인 추정치입니다.

제안 된 스키마

나는 "올바르게"(즉, 미친 것처럼 데이터를 정규화) 일을 할 계획이므로 runs테이블, spectra외래 키가 runs있는 datapoints테이블 및에 외래 키가 있는 테이블이 spectra있습니다.

200 억 데이터 포인트 질문

여러 스펙트럼과 여러 번의 실행을 분석하여 수백만 행에 닿을 수있는 쿼리를 생성하려고합니다. 내가 모든 것을 올바르게 색인화한다고 가정하면 (다른 질문의 주제 임) 네트워크를 통해 수백 개의 MiB를 섞으려고하지 않는다면 MySQL 이이를 처리하는 것이 원격으로 그럴듯합니까?

추가 정보

스캔 데이터는 XML 기반 mzML 형식의 파일에서 제공 됩니다. 이 형식의 고기 <binaryDataArrayList>는 데이터가 저장된 요소에 있습니다. 각 스캔은> = 2 개의 <binaryDataArray>요소를 생성 하여 함께 2 차원 (또는 그 이상) 형식의 배열을 형성 [[123.456, 234.567, ...], ...]합니다.

이러한 데이터는 한 번만 기록되므로 업데이트 성능 및 트랜잭션 안전성은 중요하지 않습니다.

데이터베이스 스키마에 대한 나의 순진한 계획은 다음과 같습니다.

runs

| 열 이름 | 타입 |
| ------------- + ------------- |
| 아이디 | 기본 키 |
| start_time | 타임 스탬프 |
| 이름 | 바 차르 |
| ------------- + ------------- |

spectra

| 열 이름 | 타입 |
| ---------------- + ------------- |
| 아이디 | 기본 키 |
| 이름 | 바 차르 |
| 색인 | INT |
| spectrum_type | INT |
| 표현 | INT |
| run_id | 외래 키 |
| ---------------- + ------------- |

datapoints

| 열 이름 | 타입 |
| ------------- + ------------- |
| 아이디 | 기본 키 |
| spectrum_id | 외래 키 |
| mz | 더블 |
| num_counts | 더블 |
| 색인 | INT |
| ------------- + ------------- |

이것이 합리적입니까?


그래서, 당신이 추측 할 수 있듯이, 나는 실험실의 생물학자가 아닌 프로그래머입니다. 그래서 나는 실제 과학자들만큼 과학을 거의 알지 못합니다.

다음은 처리 할 데이터 종류의 단일 스펙트럼 (스캔) 플롯입니다.

뷰어 스크린 샷

소프트웨어의 목표는 피크가 어디에서 얼마나 중요한지 파악하는 것입니다. 우리는 지금 독점 소프트웨어 패키지를 사용하여이를 파악하지만, 자체 분석 프로그램 (R)을 작성하여 도대체 무슨 일이 벌어지고 있는지 알기를 원합니다. 보시다시피, 대부분의 데이터는 흥미롭지 않지만 알고리즘에서 놓친 잠재적으로 유용한 데이터는 버리고 싶지 않습니다. 만족할만한 피크 목록이 만들어지면 나머지 파이프 라인은 원시 데이터 포인트 목록 대신 해당 피크 목록을 사용합니다. 원시 데이터 포인트를 큰 얼룩으로 저장하는 것이 충분하므로 필요할 경우 다시 분석 할 수 있지만 피크 만 별개의 데이터베이스 항목으로 유지하십시오. 이 경우 스펙트럼 당 최대 수십 개의 피크가 있으므로 미친 스케일링 요소는 '



8
이것은 원시 A / D 폴링 질량 분석기 데이터이기 때문에 실제로 데이터베이스에 저장하는 것은 멍청한 것 같습니다. 원시 데이터를 가져 와서 덤프하고 처리하고 처리 된 결과를 데이터베이스에 저장합니다. 결과는 (a) 행당 하나의 파형을 저장 한 파형, (b) 교정 곡선과 같은 해당 파형과 관련된 기타 데이터 및 (c) 데이터베이스의 결과 행입니다. 이렇게하면 디자인에서 수십억 줄의 팽창이 줄어 듭니다. 초기 분석을 다시 실행하려면 일부 매개 변수를 효과적으로 편집하고 대규모 계산 작업을 실행하며 새로운 결과를 db에 저장해야합니다.
워렌 P

답변:


115

나는 당신의 요구에 익숙하지 않지만 아마도 데이터베이스에 각 데이터 포인트를 저장하는 것은 약간 과잉입니다. 관계형 데이터베이스에 각 픽셀을 별도의 레코드로 저장하여 이미지 라이브러리를 저장하는 방식과 거의 비슷합니다.

일반적으로 이진 데이터를 데이터베이스에 저장하는 것은 대부분 잘못된 것입니다. 일반적으로 문제를 해결하는 더 좋은 방법이 있습니다. 이진 데이터를 관계형 데이터베이스에 저장하는 것은 본질적으로 잘못된 것은 아니지만 종종 단점이 이득보다 중요합니다. 이름에서 알 수 있듯이 관계형 데이터베이스는 관계형 데이터를 저장하는 데 가장 적합합니다. 이진 데이터는 관계가 없습니다. 데이터베이스에 크기를 늘리고 (대개 크게) 성능을 저하시킬 수 있으며 수십억 레코드의 MySQL 인스턴스를 유지 관리하는 데 대한 질문으로 이어질 수 있습니다. 좋은 소식은 이진 데이터를 저장하는 데 특히 적합한 데이터베이스가 있다는 것입니다. 그중 하나는 항상 쉽게 알 수는 없지만 파일 시스템입니다! 바이너리 파일을위한 디렉토리와 파일 이름 구조를 생각해 보자.

다른 접근 방식은 데이터 포인트 (및 스펙트럼) 데이터에 문서 기반 스토리지 시스템을 사용하고 실행에 MySQL을 사용하는 것입니다 (또는 실행을 다른 것과 동일한 DB에 배치하는 것).


5
이진 데이터를 데이터베이스에 저장하는 것이 왜 잘못된 것으로 간주됩니까? (호기심이 많지만 유스 케이스를 생각할 수 있기 때문에 부분적으로 요청)

15
이진 데이터에 개별적으로 값이 없으면 고유 한 행으로 저장해서는 안됩니다. 이미지의 픽셀 500x325는 관련이 없습니다.

1
아주 좋은 지적입니다. 나중에 파일을 다시 가져와야 할 경우를 대비하여 원시 파일을 보관해야하지만 이미지 저장과의 유추는 훌륭합니다. 피크 추출을 다시 실행하지 않는 한 각 데이터 포인트에 액세스 할 필요가 없으므로 추출 된 통계 정보를 저장하는 것이 훨씬 좋습니다.
haxney

107

한때 매우 큰 (테라 바이트 +) MySQL 데이터베이스로 작업 한 적이 있습니다. 우리가 가진 가장 큰 테이블은 문자 그대로 10 억 행이 넘었습니다. 이것은 MySQL 5.0을 사용했기 때문에 상황이 개선되었을 수 있습니다.

효과가있었습니다. MySQL은 대부분의 시간에 데이터를 올바르게 처리했습니다. 그러나 그것은 매우 다루기 힘들었다. (테라 바이트의 데이터로 6 시그마 수준의 가용성을 원한다면 MySQL을 사용하지 마십시오. 우리는 DBA가없고 자금이 부족한 신생 기업이었습니다.)

데이터를 백업하고 저장하는 것만으로도 문제가되었습니다. 필요한 경우 테이블을 복원하는 데 며칠이 걸릴 것입니다.

우리는 10-1 억 행 범위에 수많은 테이블을 가지고있었습니다. 테이블에 대한 중요한 조인은 시간이 너무 많이 걸리고 시간이 오래 걸립니다. 그래서 우리는 저장 프로 시저를 작성하여 'id'범위에 대해 테이블과 프로세스 조인을 '걷습니다' 이런 식으로 데이터를 한 번에 10-100,000 개의 행으로 처리합니다 (ID의 1-100,000, 그 다음 100,001-200,000 등으로 조인). 전체 테이블에 대해 조인하는 것보다 훨씬 빠릅니다.

기본 키를 기반으로하지 않는 매우 큰 테이블에서 인덱스를 사용하는 것도 훨씬 어렵습니다. MySQL 5.0은 인덱스를 두 부분으로 저장한다-인덱스 (기본 인덱스 이외)를 기본 키 값에 대한 인덱스로 저장한다. 따라서 인덱스 조회는 두 부분으로 이루어집니다. 첫 번째 MySQL은 인덱스로 이동하여 찾아야하는 기본 키 값을 가져온 다음 기본 키 인덱스에서 두 번째 조회를 수행하여 해당 값이있는 위치를 찾습니다.

이것의 장점은 테이블에 대한 매우 큰 테이블 (1-200 백만 + 행) 인덱싱이 더 제한적이라는 것입니다. 더 적은 수의 간단한 색인이 필요합니다. 그리고 인덱스에 직접 있지 않은 간단한 select 문도 다시는 돌아올 수 없습니다. where 절 색인을 누르거나 잊어 버려야합니다.

그러나 그 모든 것이 실제로 작동했습니다. 우리는 이러한 매우 큰 테이블에서 MySQL을 사용하고 계산을 수행하고 올바른 답변을 얻을 수있었습니다.

2 천억 행에 달하는 데이터를 분석하려면 고급 하드웨어와 많은 손을 잡고 인내해야합니다. 데이터를 복원 할 수있는 형식으로 백업하는 것만으로도 중요한 작업입니다.

미친 것처럼 데이터정규화하는 것은 좋은 생각이 아닐 수도 있다는 srini.venigalla의 답변에 동의합니다 . 많은 양의 데이터로 여러 테이블에서 조인을 수행하면 파일 정렬 의 위험에 노출되어 일부 쿼리가 다시는 나타나지 않을 수 있습니다. 간단한 정수 키로 비정규 화하면 성공할 가능성이 높아집니다.

우리가 가진 모든 것은 InnoDB였습니다. MyISAM과 InnoDB의 경우 : 가장 중요한 것은이 둘을 섞지 않는 것입니다. MySQL이 키와 다른 데이터를 캐시하는 방식 때문에 서버를 실제로 최적화 할 수는 없습니다. 가능하면 서버의 모든 테이블에 대해 하나 또는 다른 테이블을 선택하십시오. MyISAM은 속도 문제에 도움이 될 수 있지만 전체 DBA 작업에는 도움이되지 않을 수 있습니다.


1
MySQL은 5.0 이후 인덱스 (...) 부서에서 많이 향상되었습니다. 그것이 지금 어떻게 행동하는지 보는 것은 흥미로울 것입니다.
반지 Ø

70

미친 것처럼 데이터 정규화

이 경우 미친 것처럼 데이터를 정규화하는 것이 올바른 전략이 아닐 수 있습니다. 데이터를 정규화 된 형식과 응용 프로그램에 가장 적합한 구체화 된보기 형식으로 저장하여 옵션을 열어 둡니다. 이 유형의 응용 프로그램의 핵심은 임시 쿼리를 작성하지 않는 것입니다. 쿼리 모델링은 데이터 모델링보다 중요합니다. 대상 쿼리부터 시작하여 최적의 데이터 모델을 향해 노력하십시오.

Is this reasonable?

또한 모든 데이터가 포함 된 추가 플랫 테이블을 작성합니다.

run_id | spectrum_id | data_id | <data table columns..> |

이 테이블을 모든 쿼리의 기본 소스로 사용합니다. 그 이유는 조인을 수행하지 않아도되기 때문입니다. 인덱싱이없는 조인은 시스템을 매우 사용할 수 없게 만들며, 이렇게 큰 파일에 대한 인덱스는 끔찍합니다.

전략은 위의 테이블을 먼저 쿼리하고 결과를 임시 테이블에 덤프하고 임시 테이블을 Run 및 Spectrum의 조회 테이블과 조인하여 원하는 데이터를 얻는 것입니다.


쓰기 요구와 읽기 요구를 분석 했습니까? SQL을 버리고 비표준 데이터 저장 메커니즘으로 이동하는 것이 매우 유혹적입니다. 제 생각에는 최후의 수단이되어야합니다.

쓰기 속도를 높이려면 처리기 소켓 방법을 사용해보십시오. Percona는 기억한다면 Handler Socket을 설치 패키지에 패키지합니다. (Percona와 관련이 없습니다!)

http://yoshinorimatsunobu.blogspot.com/2010/10/using-mysql-as-nosql-story-for.html


33

짧은 대답은 예입니다. 행 수가 많을수록 정확한 스키마, 데이터 유형 및 선택한 작업이 중요해집니다.

데이터를 정규화하는 정도는 저장된 데이터에 대해 수행하려는 작업에 따라 다릅니다. 특히 '데이터 포인트'테이블에 문제가있는 것 같습니다. 특정 스펙트럼의 n 번째 포인트를 다른 스펙트럼의 m 번째와 비교할 계획입니까? 그렇지 않으면 별도로 저장하는 것이 실수 일 수 있습니다. 데이터 포인트가 독립적이지 않고 관련 스펙트럼의 맥락에서만 이해되는 경우 PRIMARY KEY가 필요하지 않습니다. 스펙트럼에 대한 외래 키와 'nth'열 ( '인덱스'열?)이면 충분합니다. .

수행해야하는 스펙트럼 간 및 스펙트럼 내 작업을 정의한 다음 가장 저렴한 방법을 찾아야합니다. 평등이 필요한 모든 경우 비정규 화 될 수 있습니다. 아마도 작업을 지원하는 미리 계산 된 통계 메타 데이터가있을 수 있습니다. 개별 데이터 포인트에 대한 SQL 내 액세스가 절대적으로 필요한 경우 각 행의 크기를 최소 필드 수와 가능한 최소 데이터 유형으로 줄이십시오.

내가 개인적으로 관리 한 가장 큰 MySQL은 ~ 1 억 행이었습니다. 이 크기에서 행과 필드를 고정 크기유지하려고합니다-MySQL 은 각 행의 고정 크기 (포인터 산술 생각)를 곱하여 테이블의 행 위치를 효율적으로 계산할 수 있습니다 . 정확한 세부 사항은 사용하려는 스토리지 엔진에 따라 다릅니다. MyISAM을 사용할 수있는 경우, 속도가 느리거나 안정성이 부족한 상황에서 충분하면 MyISAM을 사용하십시오. VARCHAR과 같은 가변 크기 필드를 CHAR (n)으로 바꾸고 읽기 쿼리에서 RTRIM ()을 사용하십시오.

테이블 행의 너비가 고정되면 MySQL의 정수 데이터 유형 (일부는 비표준) 을 신중하게 평가하여 바이트 수를 줄일 수 있습니다 . 4 바이트 INT를 3 바이트 MEDIUMINT로 변환하여 1 바이트를 절약 할 수있을 때마다 백만 행당 ~ 1MB를 절약 할 수있어 디스크 I / O가 줄어들고보다 효과적인 캐싱이 가능합니다. 제거 할 수 있는 가장 작은 데이터 유형을 사용하십시오 . 부동 소수점 유형을 신중하게 평가하고 8 바이트 DOUBLE을 4 바이트 FLOAT 또는 <8 바이트 고정 소수점 숫자로 대체 할 수 있는지 확인하십시오 . 당신이 선택한 것이 나중에 물지 않도록 테스트를 실행하십시오.

데이터 집합의 예상 속성과 필요한 작업에 따라 값의보다 특이한 인코딩 (값 집합으로 색인으로 인코딩 할 수있는 예상 패턴 / 반복, 의미있는 기여 만 할 수있는 원시 데이터)이 추가로 절약 될 수 있습니다. 이국적인, 직관적이지 않고 파괴적인 최적화는 다른 모든 옵션을 시도했을 때만 가치가 있습니다.

가장 중요한 것은, 무엇을하든 완벽한 스키마를 선택한 다음 천만 개의 레코드를 맹목적으로 시작한다고 가정하지 마십시오. 좋은 디자인은 진화하는 데 시간이 걸립니다. 대규모이지만 관리하기 쉬운 (1-5 %) 테스트 데이터 세트를 작성하고 스키마의 정확성과 성능을 검증하십시오. 다양한 작업 수행 방법 (http://dev.mysql.com/doc/refman/5.0/en/using-explain.html)을 확인하고 가장 자주 사용하는 작업에 유리하도록 스키마 균형을 유지하십시오.

내가 짧게 말 했니? 으악. 어쨌든 행운을 빌어 요!


23

데이터 포인트 데이터를 XML에서 (시간 및 실행 유형과 같은 메타 데이터와 달리) 데이터베이스 형식으로 파쇄하는 유일한 이유는 배열에서 스펙트럼을 분석 할 때입니다. 특정 서명으로 실행됩니다. 지금 당장은 문제 도메인을 알고 있지만 96kHz로 샘플링 된 음악을 행당 1 개의 샘플로 저장하는 것과 비슷할 수 있습니다. 데이터가 사용되는 방법보다 크기가 문제인지 확실하지 않습니다. 데이터를 쿼리하는 것은 비틀즈가 모든 노래에서 노래에 상대 진폭을 2 분 동안 묻는 것과 같습니다. 수행 할 수있는 분석의 종류를 알고 있다면 신호에 대해 분석을 수행하고 실행에 대한 메타 데이터에 저장하는 것이 더 합리적 일 수 있습니다.

소스 데이터가 희소 한지도 확실하지 않습니다. 데이터베이스의 스펙트럼에는 0이 아닌 항목 만 포함되어야하고 원본 XML에는 0이 아닌 항목 만 포함해야하므로 총 행 수가 소스 데이터보다 훨씬 적을 수 있습니다.

따라서 많은 질문과 마찬가지로 MySQL이 모델을 처리하고, 물러서서 모델을 살펴보고 사용하는 방법에 대해 질문하기 전에 아직 성능에 대해 걱정하는 것보다 더 적합 할 것입니다.


질문 업데이트를 검토 한 후 이진 데이터가 BLOB으로 저장되거나 파일에 대한 포인터로 모델이 충분하다고 생각하고 데이터가 처음 발견되었을 때 식별 된 중요한 피크에 대한 데이터를 저장하도록 모델을 수정하는 작업을 수행합니다. 읽다.


18

약 50 개의 데이터베이스 서버로 웹 분석 서비스를 실행합니다. 각 서버에는 1 억 개가 넘는 행과 많은 수의 행이 10 억 개가 넘고 때로는 20 억 개가 넘습니다 (각 서버에서).

여기의 성능은 괜찮습니다. 매우 정규화 된 데이터입니다. 그러나 이것을 읽는 것에 대한 나의 주요 관심사는 당신이이 테이블들에 대해 42 억 행을 넘을 것이라는 것입니다 ( "실행"이 아니라 아마도 다른 두 개), INT 대신 BIGINT를 사용해야합니다. 기본 / 외국 키.

인덱스 열에서 BIGINT 필드의 MySQL 성능은 INT에 비해 엄청나게 끔찍 합니다. 나는이 크기보다 커질 것으로 생각되는 테이블 로이 작업을 한 번 실수했으며, 수억 행에 도달하면 성능이 단순히 무섭습니다. 나는 원시 숫자가 없지만 나쁜 말을하면 Windows ME가 나쁜 것을 의미합니다.

이 열은 기본 키였습니다. 우리는 그것을 단지 INT로 바꾸었고 presto magico로 성능이 다시 좋았습니다.

당시 우리의 모든 서버는 데비안 5와 MySQL 5.0을 사용했습니다. 이후 데비안 6 및 Percona MySQL 5.5로 업그레이드 했으므로 그 이후로 상황이 개선되었을 수 있습니다. 그러나 여기에서의 나의 경험에 따르면, 나는 그것이 잘 작동하지 않을 것이라고 생각합니다.


17

작동 여부에 관계없이 단일 모 놀리 식 저장 매체에서 항상 같은 문제가 발생합니다. 디스크 속도가 느립니다. 100MB / s (스피닝 미디어에 매우 좋음)에서는 1TB 테이블 을 읽는 데 3 시간이 걸립니다 . 그것은 분석이나 탐색 또는 다른 지연이 속도를 늦추고 있다고 가정합니다.

이것이 거의 모든 "빅 데이터"설치가 일종의 분산 데이터 저장소를 사용하는 이유입니다. DB를 실행할 수있는 놀라운 컴퓨터 한 대를 만드는 데 8 배나 더 많은 비용을 소비 할 수 있지만, 동시에 스캔 할 수있는 데이터가 많으면 8 대의 저렴한 컴퓨터에로드를 분산시키는 것이 거의 항상 유리합니다.

hadoop 과 같은 프로젝트는 이와 같은 목적으로 특별히 빌드되었습니다. 저렴한 컴퓨터 묶음으로 클러스터를 구축하고 모든 컴퓨터에 데이터를 분산시킨 후 병렬로 쿼리합니다. 이 아이디어를 바탕으로 구축 된 6 가지 솔루션 중 하나 일 뿐이지 만 매우 인기있는 솔루션입니다.


13

흠 ... 이런 종류의 데이터 구조를 선택해야하는 이유는 두 가지뿐입니다.

  • 데이터 포인트와 데이터 포인트 쿼리를 수행해야합니다.
  • SQL에서 모든 논리를 수행하려고합니다.

이제 귀하의 요구 사항을 자세히 살펴보고 위의 가정 중 하나 이상이 사실인지 확인하십시오. 둘 다 사실이 아니라면, 당신은 일을 더 느리게 만드는 것입니다. 이러한 종류의 데이터 세트의 경우 먼저 데이터에 액세스하는 방법, 필요한 정확도 등을 확인한 다음 데이터베이스를 설계하십시오.

추신 : 데이터 포인트 당 최소 36 + 5 바이트가 필요하므로 200B 데이터 포인트를 사용하면 8.2TB 이상의 필요한 공간이 필요합니다.

PPS : 테이블에 id열이 필요하지 않습니다 datapoints. PRIMARY KEY (spectrum_id, index)아마도 충분할 것입니다 ( index예약어 일 수 있음에 주의하십시오 ).


12

편집하다:

단일 디스크에 저장된 데이터를 사용하여 MYSQL에서이 작업을 수행하지 마십시오. 단일 매체에서 해당 양의 데이터를 읽는 데 몇 시간이 걸립니다. 업이 아닌 스케일 아웃해야합니다.

효과적인 데이터 분석을 수행하려면 데이터를 비정규 화해야합니다. 온라인 시스템을 설계하지 않았습니다. 당신은 숫자를 위기에 따라 디자인하고 싶습니다.

아래의 원래 답변.


답변은 쿼리에 따라 다를 수 있습니다. MySQL이이 작업에 가장 적합한 도구가 아닐 수도 있습니다. "확대"가 아니라 "확대"할 수있는 솔루션을 살펴볼 수 있습니다. 약간의 노력을 기울이고 싶다면 Hadoop과 같은 Map Reduce 솔루션을 살펴보십시오.

더 많은 임시 쿼리를 수행하려는 경우 Google의 BigQuery 솔루션이 적합 할 수 있습니다. Google I / O 2012의 관련 프리젠 테이션 : BigQuery를 사용하여 빅 데이터 크 런칭

따라서 솔루션은 이것이 일회성인지 여부와 임시 쿼리를 합리적으로 지원 하려는지에 달려 있습니다.


9

아무도 언급하지 않았으므로 내 제안. 대규모 샤딩 된 MySQL 솔루션을 살펴보십시오 . 예를 들어,이 텀블러 프레젠테이션을 참조하십시오 .

개념은 다음과 같습니다.

  • 하나의 초대형 데이터베이스 대신
  • 원본 데이터의 일부를 보유한 많은 작은 것들을 사용하십시오.

따라서 수직 성능을 향상시키는 대신 수평으로 확장 할 수 있습니다. Google의 BigTableGFS 는 저렴한 수평 확장 가능 노드를 사용하여 페타 바이트의 데이터를 저장하고 쿼리합니다.

그러나 다른 샤드에서 쿼리를 실행해야하는 경우 문제가 발생합니다.


관심있는 사람은 얼마 전에 안녕하세요 세계 샤딩 응용 프로그램을 만들었습니다. 블로그 게시물에서 여기 에 설명되어 있습니다 . RavenDB와 C #을 사용했지만 세부 사항은 관련이 없으며 아이디어는 동일합니다.


7

데이터는 어떤 종류의 머신에 저장됩니까? 공유 저장 장치입니까?

쿼리 시간을 결정 짓는 궁극적 인 요소는 하드 드라이브가 될 것입니다. 데이터베이스 및 해당 쿼리 최적화 프로그램은 디스크 I / O 수를 최대한 줄 이도록 설계되었습니다. 테이블이 3 개 밖에 없다는 점을 감안하면이 작업은 매우 안정적으로 수행됩니다.

하드 드라이브의 읽기 / 쓰기 속도는 메모리 속도보다 200-300 배 느립니다. 대기 시간이 매우 빠르고 읽기 및 쓰기 속도가 빠른 하드 드라이브를 찾으십시오. 이 모든 데이터가 하나의 2TB 드라이브에 있으면 쿼리가 완료되기까지 오랜 시간이 걸릴 수 있습니다. 하드 드라이브 대기 시간은 ~ 10-15 밀리 초이며 메모리 대기 시간은 10nanoseconds 미만입니다. 하드 드라이브 대기 시간은 메모리 대기 시간보다 1000-2000x 느릴 수 있습니다. 하드 드라이브에서 기계 팔을 움직이는 것은이 전체 시스템에서 가장 느린 것입니다.

당신은 얼마나 많은 RAM을 가지고 있습니까? 16 기가 바이트? 32 개의 레코드를 보유 할 수 있습니다. 16000 개의 파일이 있습니다. 모든 데이터 포인트를 선형 스캔하려면 탐색 시간만으로 5-10 초로 쉽게 끝날 수 있습니다. 그런 다음 전송 속도를 50mb / s로 고려 하시겠습니까? 약 7 시간 또한 새로운 데이터를 읽을 공간을 확보하기 위해 임시 저장된 데이터를 하드 디렉토리에 저장해야합니다.

다른 사용자가 적극적으로 사용하는 공유 저장 장치를 사용하는 경우 가장 좋은 방법은 밤에 모든 것을 실행하는 것입니다.

중첩 된 쿼리 수를 줄이는 것도 도움이됩니다. 중첩 된 쿼리는 임시 테이블을 생성하여 하드 드라이브를 더 많이 손상시킵니다. 하드 드라이브에 충분한 여유 공간이 있기를 바랍니다.

쿼리 최적화는 한 번에 하나의 쿼리 만 볼 수 있습니다. 따라서 중첩 된 select 문을 최적화 할 수 없습니다. 그러나 특정 중첩 쿼리로 인해 작은 데이터 집합이 반환 될 것이라는 것을 알고 있다면 유지하십시오. 쿼리 최적화는 히스토그램과 대략적인 가정을 사용합니다. 데이터와 쿼리에 대해 알고 있다면 계속 진행하십시오.

데이터가 디스크에 저장되는 방식에 대해 더 많이 알수록 쿼리를 더 빨리 작성할 수 있습니다. 모든 것이 기본 키에 순차적으로 저장된 경우 중첩 된 쿼리에서 반환 된 기본 키를 정렬하는 것이 좋습니다. 또한 사전에 분석해야 할 데이터 집합 집합을 줄일 수 있다면 그렇게하십시오. 시스템에 따라 파일 당 약 1 초의 데이터 전송을 확인합니다.

이름 값 (varchars)을 수정하려는 경우 최대 크기의 데이터 유형으로 변경하면 조각화가 방지되고 메모리는 몇 바이트 더 늘어납니다. 최대 값이 100 인 NVARCHAR 일 수 있습니다.

테이블을 비정규 화하는 것에 대한 의견. 데이터 포인트를 더 큰 그룹 (스펙트로)에 저장 한 다음 파이썬이나 데이터베이스와 상호 작용하는 언어로 데이터 분석을 수행하는 것이 가장 좋습니다. SQL-Wizard가 아닌 한.


3
하드 드라이브와 메모리 대기 시간의 큰 차이를 강조하지만 숫자가 1000 배로 줄어 듭니다. 하드 드라이브의 대기 시간이 약 10ms이고 메모리가 10ns 인 경우 대기 시간은 1,000 배가 아니라 1,000,000!
spectre256

6

나에게 여기에 설명 된 "관계형 열 저장소" 같은 것을 원하는 사용 시나리오처럼 들립니다 .

디자인을 잘못 이해했을 수도 있지만 주로 대규모 배열 컬렉션을 처리하는 경우 일반적인 행 지향 테이블에 저장하면 각 요소가 슬라이스와 유사하다는 것을 의미합니다. 일반적인 방식으로 슬라이스를 보는 데 관심이 있다면 의미가 있지만 한 번에 전체 열을 실제로 보는 경우 효율성이 떨어질 수 있습니다.

배열을 검색 할 때 정규화로 인해 다른 테이블과 배열을 조인 할 필요가 없을뿐만 아니라 시리즈를 해시가 아닌 배열로 검색 할 수 있습니다.

나는 실제로 문제를 오해하고있을 수도 있으며 특정 해결책을 제안하지도 않습니다.

실제로 현재 또는 배포 가능한 솔루션이 아니더라도 관련성이있는 또 다른 대화 가 있습니다.


6

테이블을 분할하고 파티션을 나누는 것이 좋습니다. 단일 테이블 (주식 시장 데이터)에 80 만 개가 넘는 행이 있으며 빠르게 액세스하는 데 어려움이 없습니다.

데이터 검색 방법에 따라 파티션을 설계해야합니다. 우리의 경우 날짜 별은 특정 날짜를 쿼리하기 때문에 잘 작동합니다.

http://dev.mysql.com/doc/refman/5.1/en/partitioning-limitations.html

http://www.slideshare.net/datacharmer/mysql-partitions-tutorial


5

네,하지만...

나는 20 억 행이있는 테이블로 작업했습니다. 그러나 PK를 사용하는 쿼리 만 빠른 것으로 예상되었습니다.

가장 중요한 것은 하드웨어에 전체 테이블을 메모리에 맞추기에 충분한 RAM이 있다는 것입니다. 이것이 문제가되었을 때 (당시 최대 96GB), 수직 분할을 수행하여 각 머신의 테이블 세트 크기를 메모리에 맞출 수있을 정도로 작게 유지했습니다. 또한 시스템은 10Gb 파이버를 통해 연결되었으므로 네트워크 처리량은 그다지 큰 문제가되지 않았습니다.

BTW. 스키마는 run_id스펙트럼의 spectrum_id해싱 키와 데이터 포인트의 해싱 키로 사용하여 NoSQL 솔루션에 적합한 것으로 보입니다 .


4

내 블로그 에이 주제에 대해 썼습니다 : http://www.tocker.ca/2013/10/24/improving-the-performance-of-large-tables-in-MySQL.html

핵심 사항 중 일부를 반복하려면

  • B- 트리는 더 커지고 메모리에 맞지 않으면 성능이 저하됩니다 (MySQL은 여기에만 없습니다).
  • InnoDB에는 성능을 유지하는 데 도움이되는 몇 가지 기능이 있습니다 (버퍼링 변경, 이전에는 '삽입 버퍼'라고 함).
  • 파티셔닝도 도움이 될 수 있습니다.

내 게시물 Tim Callaghan의 의견에서 이것에 링크되었습니다 : http://www.tokutek.com/resources/benchmark-results/benchmarks-vs-innodb-hdds/#iiBench

iibench 벤치 마크를 사용하여 10 억 개의 행을 삽입하는 것을 보여줍니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.