今天下午和同事发生因为判断数据是否在数据库中已存在产生分歧.简易代码如下:
//观点一,先取出数据库中已存在ID存入内存,再进行判断
//数据太多情况,内存爆炸
DateTable dt = ExcuteSQL('SELECT ID FROM TABLE');
//List为数据集,已经去重
foreach(var item in List){
//观点二,在for循环中根据ID查询是否已存在
//for循环执行数据库?没这么干过
DateTable dt = ExcuteSQL(string.format('SELECT ID FROM TABLE WHERE ID = {0}',item.ID));
//判断是否在dt中存在
...
bool ISContain
...
//不存在
if(!ISContain){
//加入事物SQL列表
SQLList.Add('INSERT INTO ........');
}
}
//执行事物
....
実際、最初に実際のデータ量に基づいて見積もる必要があります。ID が Long タイプで、データ量が 100W の場合、データ量は 8 バイト * 100W = 7.629 メガバイトになります。
2 番目の項目は絶対に必要で、ループ内で各 ID をクエリします。
推奨方法 2 ですが、このクエリの方が高速です:
リーリーデータベースごとにパラメータに制限があることに注意してください。
?
1,000 を超えないことが最善です。 10,000 個の ID を特定する必要がある場合は、そのようなクエリを 10 回使用します。@aunt yellow が言及した方法を使用し、バッチでクエリを実行する方が良いはずです。 IDが多い場合は他のバッチ方法で確認できないか検討してみてはいかがでしょうか?たとえば、一定期間のすべての
id
を一度に取得し、これを達成するために方法 1 を少し改良します。方法 1 と方法 2 はどちらも極端なように感じられるため、良い解決策は両方を組み合わせる必要があります。
https://www.zhihu.com/questio...
データベースアクセスを減らすために、まずデータベースからIDを取り出してからメモリ内で比較する方法を使用することをお勧めします。
メモリにセグメント化することでメモリ使用量を削減できますか?