web-dev-qa-db-ja.com

すべてのAzureテーブルレコードを削除する

Azure Storage Tableがあり、3k以上のレコードがあります。

テーブル内のすべての行を削除する最も効率的な方法は何ですか?

15
CmdrTallen

3000レコードの場合、最も簡単な方法は テーブルを削除する です。ただし、テーブルを削除すると、その時点では削除されず、ある種のキューに入れられて削除され、実際にはしばらくしてから削除されることに注意してください。この時間は、システムの負荷+テーブル内のエンティティの数によって異なります。この間、このテーブルを再作成したり、このテーブルを使用したりすることはできません。

テーブルを使い続けることが重要な場合、他の唯一のオプションはエンティティを削除することです。削除を高速化するには、 Entity Batch Transactions を使用してエンティティの削除を確認できます。ただし、エンティティを削除するには、最初にエンティティをフェッチする必要があります。エンティティの削除にはこれら2つの属性のみが必要であるため、すべての属性をフェッチするのではなく、エンティティのPartitionKey属性とRowKey属性のみをフェッチすることで、フェッチプロセスを高速化できます。

20
Gaurav Mantri

私はこのようなものを使用します。キーを日付で分割します。ケースが異なる場合があります。

async Task Main()
{
    var startDate = new DateTime(2011, 1, 1);
    var endDate = new DateTime(2012, 1, 1);

    var account = CloudStorageAccount.Parse("connString");
    var client = account.CreateCloudTableClient();
    var table = client.GetTableReference("TableName");

    var dates = Enumerable.Range(0, Math.Abs((startDate.Month - endDate.Month) + 12 * (startDate.Year - endDate.Year)))
        .Select(offset => startDate.AddMonths(offset))
        .ToList();

    foreach (var date in dates)
    {
        var key = $"{date.ToShortDateString()}";

        var query = $"(PartitionKey eq '{key}')";
        var rangeQuery = new TableQuery<TableEntity>().Where(query);

        var result = table.ExecuteQuery<TableEntity>(rangeQuery);
        $"Deleting data from {date.ToShortDateString()}, key {key}, has {result.Count()} records.".Dump();

        var allTasks = result.Select(async r =>
        {
            try
            {
                await table.ExecuteAsync(TableOperation.Delete(r));
            }
            catch (Exception e) { $"{r.RowKey} - {e.ToString()}".Dump(); }
        });
        await Task.WhenAll(allTasks);
    }
}
2
stack247

これはデータの構造によって異なりますが、すべてのレコードのクエリを作成できる場合は、それぞれを TableBatchOperation に追加して、一度に実行できます。

これは、同じパーティションキー内ですべての結果を取得する例であり、 AzureテーブルストレージとVisual Studio接続サービスの使用を開始する方法 から適応されています。

// query all rows
CloudTable peopleTable = tableClient.GetTableReference("myTableName");
var query = new TableQuery<MyTableEntity>();
var result = await remindersTable.ExecuteQuerySegmentedAsync(query, null);

// Create the batch operation.
TableBatchOperation batchDeleteOperation = new TableBatchOperation();

foreach (var row in result)
{
    batchDeleteOperation.Delete(row);
}

// Execute the batch operation.
await remindersTable.ExecuteBatchAsync(batchDeleteOperation);
0
KyleMit

次の関数を使用して、最初にすべてのパーティションキーをキューに入れ、次にキーをループして100のバッチですべての行を削除します。

Queue queue = new Queue();
            queue.Enqueue("PartitionKeyTodelete1");
            queue.Enqueue("PartitionKeyTodelete2");
            queue.Enqueue("PartitionKeyTodelete3");

            while (queue.Count > 0)
            {
                string partitionToDelete = (string)queue.Dequeue();

                TableQuery<TableEntity> deleteQuery = new TableQuery<TableEntity>()
                  .Where(TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, partitionToDelete))
                  .Select(new string[] { "PartitionKey", "RowKey" });

                TableContinuationToken continuationToken = null;

                do
                {
                    var tableQueryResult = await myTable.ExecuteQuerySegmentedAsync(deleteQuery, continuationToken);

                    continuationToken = tableQueryResult.ContinuationToken;

                    // Split into chunks of 100 for batching
                    List<List<TableEntity>> rowsChunked = tableQueryResult.Select((x, index) => new { Index = index, Value = x })
                        .Where(x => x.Value != null)
                        .GroupBy(x => x.Index / 100)
                        .Select(x => x.Select(v => v.Value).ToList())
                        .ToList();

                    // Delete each chunk of 100 in a batch
                    foreach (List<TableEntity> rows in rowsChunked)
                    {
                        TableBatchOperation tableBatchOperation = new TableBatchOperation();
                        rows.ForEach(x => tableBatchOperation.Add(TableOperation.Delete(x)));

                        await myTable.ExecuteBatchAsync(tableBatchOperation);
                    }
                }
                while (continuationToken != null);
            }
0
datapool