2011-09-07 3 views
13

고객이 메시지를 게시하는 Azure 테이블이 있는데 한 테이블에 수백만 개의 메시지가있을 수 있습니다. 지난 10 분 내에 메시지를 게시하는 가장 빠른 방법을 찾고 싶습니다 (웹 페이지를 새로 고치는 빈도수). 파티션 키만 인덱싱되었으므로 메시지가 파티션 키 (예 : "2009-06-15T13 : 45 : 30.0900000"Azure 테이블의 최신 항목을 쿼리하는 가장 빠른 방법은 무엇입니까?

과 같은 ISO8601 날짜 형식의 문자열)로 게시 된 날짜 & 시간을 사용한다는 아이디어를 가지고 놀았습니다.

예 의사 코드 : 다음

var message = "Hello word!"; 
var messagePartitionKey = DateTime.Now.ToString("o"); 
var messageEntity = new MessageEntity(messagePartitionKey, message); 
dataSource.Insert(messageEntity); 

,이 같은 마지막 10 분 이내에 게시 된 메시지를 쿼리 (다시 안된 의사 코드) :

// Get the date and time 10 minutes ago 
var tenMinutesAgo = DateTime.Now.Subtract(new TimeSpan(0, 10, 0)).ToString("o"); 

// Query for the latest messages 
var latestMessages = (from t in 
    context.Messages 
    where t.PartitionKey.CompareTo(tenMinutesAgo) <= 0 
    select t 
    ) 

그러나 이것은으로 잘 이동합니다 색인? 또는 전체 테이블 스캔이 발생합니까? 누구나이 일을 더 잘 할 수 있을까요? 나는 각 테이블 항목에 타임 스탬프가 있음을 알고 있지만 인덱싱되지 않으므로 내 용도로는 너무 느릴 것입니다.

+0

사이드 노트로, 좀 더 일반적인 것을 파티션 키로 사용해야합니다. 귀하의 게시물이 속한 곳과 같습니다. http://msdn.microsoft.com/en-us/library/windowsazure/hh508997.aspx –

+0

같은 컴퓨터가 삽입과 쿼리를 모두 수행하고 있습니까? 그렇지 않은 경우 클라이언트 간의 잠재적 인 클럭 왜곡을 고려해야합니다. –

답변

5

나는 당신이 바른 기본 생각을 가지고 있다고 생각한다. 설계 한 쿼리는 원하는만큼 효율적이어야합니다. 그러나 내가 제공 할 수있는 몇 가지 개선점이 있습니다.

DateTime.Now을 사용하는 대신 Date.UtcNow을 사용하십시오. 나는 인스턴스가 기반으로 Utc 시간을 사용하도록 설정되어 있음을 알고 있지만 사과와 사과를 비교하고 신뢰할 수있는 시간대를 표시 할 때 원하는 시간대로 되돌릴 수 있습니다.

.ToString("o") 시간을 틱으로 저장하고 저장하면 서식 문제가 줄어들어 결국 때로는 표준 시간대 사양을 얻을 수 있습니다. 또한 가장 최근부터 가장 오래된 메시지를 항상 정렬하려는 경우 최대 틱 수에서 틱 수를 뺄 수 있습니다.

var messagePartitionKey = (DateTime.MaxValue.Ticks - _contactDate.Ticks).ToString("d19"); 

행 키를 지정하는 것도 좋은 방법입니다. 두 개의 메시지가 정확히 같은 시간에 게시되는 것은 거의 불가능하지만 불가능하지는 않습니다. 명백한 행 키가 없다면 그냥 Guid로 설정하십시오.

+0

틱은 각 레코드마다 고유하며 각 파티션 키에 대해 단일 파티션을 만듭니다. 나는 진드기를 복용하는 것이 최선의 방법이라고 생각하지 않는다. – Kurkula

+1

예, 각 행에 대해 파티션을 만들지 만,이 상황에서는이를 수행하는 데 불리한 점이 없습니다. – knightpfhor

+0

확실하지는 않지만 여러 개의 파티션을 만들면 성능이 저하됩니다. – Kurkula

3

Diagnostics API가 WADPerformanceCountersTable을 사용하여 수행하는 것과 비슷한 작업을 제안합니다. PartitionKey는 단일 항목에 여러 개의 타임 스탬프를 그룹화합니다. 즉, 모든 타임 스탬프를 가장 가까운 몇 분 (예 : 가장 가까운 5 분)으로 반올림합니다. 이렇게하면 제한된 양의 파티션 키가 없지만 여전히 원거리 쿼리를 수행 할 수 있습니다.

따라서, 예를 들어, 당신은 등, 0시 15분, 0시 10분, 0시 5분 00:00로 반올림 각 타임 스탬프에 매핑에 PartitionKey을 가질 수 있습니다 .. 다음 틱

+0

아주 좋은 대안처럼 들리지만 내 시나리오에서는 페이지가 여러 클라이언트에서 다른 간격으로 새로 고쳐집니다. 요청이 들어 오면 클라이언트에게 동일한 메시지 또는 너무 적은 메시지를 보낼 위험이 없습니다. –

+0

나는이 아이디어를 좋아한다. – Roboblob

4
로 변환

테이블의 기본 키는 PartitionKey와 RowKey (클러스터 된 인덱스를 형성 함)의 조합입니다.

경우에 따라 ParitionKey 대신 RowKey를 사용하십시오 (이 경우 상수 값을 입력하십시오).

또한 새 파티션 키를 만들 때마다 10 분마다 진단 방법을 사용할 수 있습니다. 그러나이 접근법은 주로 Archieving/Purging 등과 같은 요구 사항에 대한 것입니다.,

0
  • 정확도가 "="인 파티션 키를 사용하는 것이 "<"또는 "보다 큼"을 사용하는 것보다 훨씬 빠릅니다.
  • 또한 조건에 맞는 파티션 키와 행 키의 고유 한 조합을 얻을 수 있다면 더 많은 노력을 기울여야합니다.
  • 더 많은 파티션을 방지하려면 고유 한 파티션 키 값의 조합을 적게 사용하십시오.
관련 문제