1

問題がある。毎日、大量のデータを更新してダウンロードする必要があります。約140メガバイト。これらのデータはファイルから取得されます。これらの非常に長くロードされた9000レコードは、10分間ロードされます。カスタムSQLサーバーを使用した場合、データの読み込みが速くなるという事実にもかかわらず。

以下は、データをロードするための私のコードです。

var InBase = FrmMain.allRecords.ToList(); 
var allcats = FrmMain.allCats;
int curCategory = 0;
            for (int jrCnt = rCnt; jrCnt <= arrayTable.GetUpperBound(0); jrCnt++)
            {
                while (operations.Count(x => x.IsAlive) >= 100) ;

                var prcI = new Price();

                if (arrayTable[jrCnt, nametov] != null)
                    prcI.name = arrayTable[jrCnt, nametov].ToString();

                if (productsInBase.FirstOrDefault(x => x.name == prcI.name) != null) 
                {
                    var finded = productsInBase.FirstOrDefault(x => x.name == prcI.name && x.company==company);
                    prcI.ID = finded.ID;
                }

                if (arrayTable[jrCnt, pricetov] != null)
                {
                    decimal parsdec;
                    if (decimal.TryParse(arrayTable[jrCnt, pricetov].ToString(), out parsdec))
                        prcI.prc = parsdec;
                }

                prcI.category = curCategory;

                if (!string.IsNullOrEmpty(prcI.name) && prcI.prc == 0)
                {
                    var cat =
                        allcats.FirstOrDefault(
                            x =>
                            x.findname != "NaN" &&
                            x.findname.ToUpper().Split(';').Any(prcI.name.ToUpper().Contains));
                    curCategory = cat == null ? 0 : cat.id;
                }

                if ((string.IsNullOrEmpty(prcI.name)) || (prcI.prc == 0)) continue;

                Products.Add(prcI);

                if (count == 0 || count % 200 != 0 && jrCnt != arrayTable.GetUpperBound(0)) continue;

                int start = count >= prodInTh ? count % prodInTh != 0 ? (count - count % prodInTh) : (count - prodInTh) : 0;
                int end = count % prodInTh != 0 ? (count % prodInTh) : prodInTh;

                var productsForThreadUpd = Products.GetRange(start, end).Where(x => x.ID != 0).ToList();

                var addprod = Products.GetRange(start, end).Where(x => x.ID == 0).ToList();

                if (productsForThreadUpd.Count > 0) 
                {
                    var newTh = new Thread(() => _mainClass.AddProductsUpdateProduct(productsForThreadUpd))
                        {
                            Name = company + start + " - " + (start + end) + " UPDATE"
                        };

                    newTh.Start();
                    operations.Add(newTh);
                }
                if (addprod.Count > 0)
                {
                    var newTh = new Thread(() => _mainClass.AddProductsUpdateProduct(addprod))
                        {
                            Name = company + start + " - " + (start + end) + " ADD"
                        };

                    newTh.Start();
                    operations.Add(newTh);
                }

            }

スレッドの負荷を分割します。obnomストリームで私の200エントリ。ブートコードデータ:

public void AddProductsUpdateProduct(List<Price> price)
        {
            using (var dcupdateoradd = new PriceDataContext())
            {
                if (price.Any(x => x.ID != 0))
                {
                    var upds = price.Where(x => x.ID != 0).ToList();
                    dcupdateoradd.Price.AttachAll(upds);
                    dcupdateoradd.Refresh(RefreshMode.KeepCurrentValues, upds);
                }

                dcupdateoradd.Price.InsertAllOnSubmit(price.Where(x => x.ID == 0));

                dcupdateoradd.SubmitChanges();
            }
        }

プログラムがプロシージャのためにデータベースに何回接続するかはまだわかりませんが、思いつくまでは何もありません。

接続

メモリの負荷:

ロードメモリ

ありがとうございました!

4

1 に答える 1

2

SQLデータベースに大量のデータを挿入する方法はいくつかあります。私のお気に入りはSqlBulkCopyです。このメソッドにはDataTableが必要であり、EntityFrameworkをバイパスします。これにより、非常に効率的な方法でレコードをSQLデータベースにストリーミングできます。これを使用して、WindowsAzureのデータベースに1日に7000万行以上を挿入します。

詳細については、次のブログをご覧ください。

これを実行するもう1つの方法は、ストアドプロシージャを使用し、テーブル値パラメーターを使用してINSERTINTOステートメントを使用できるようにすることです。このシナリオでは、DataTableをパラメーターとしてストアドプロシージャに渡すことができます。DataTableがストアドプロシージャで使用されるユーザー定義タイプと100%一致していることを確認してください。

この手法の使用に関する詳細は、次のブログで見つけることができます

9000を超えるレコードをデータベースに挿入する方法を探している場合は、必ずSqlBulkCopyを使用してください。ストアドプロシージャのアプローチは、実際には小さなデータセットに適しています。

于 2013-03-23T15:48:38.210 に答える