Mam następujący kod napisany w języku C#, ale zgodnie z tym, migracja danych z bazy danych Oracle do Elasticsearch zajmie mi 4-5 dni. Wstawiam rekordy w partiach po 100. Czy istnieje inny sposób, w którym migracja 4 milionów rekordów odbywa się szybciej (prawdopodobnie w mniej niż dzień, jeśli to możliwe)?Jak szybciej wstawić 4 miliony rekordów z Oracle do tabeli Elasticsearch przy użyciu C#?
public static void Selection()
{
for(int i = 1; i < 4000000; i += 1000)
{
for(int j = i; j < (i+1000); j += 100)
{
OracleCommand cmd = new OracleCommand(BuildQuery(j),
oracle_connection);
OracleDataReader reader = cmd.ExecuteReader();
List<Record> list=CreateRecordList(reader);
insert(list);
}
}
}
private static List<Record> CreateRecordList(OracleDataReader reader)
{
List<Record> l = new List<Record>();
string[] str = new string[7];
try
{
while (reader.Read())
{
for (int i = 0; i < 7; i++)
{
str[i] = reader[i].ToString();
}
Record r = new Record(str[0], str[1], str[2], str[3],
str[4], str[5], str[6]);
l.Add(r);
}
}
catch (Exception er)
{
string msg = er.Message;
}
return l;
}
private static string BuildQuery(int from)
{
int to = from + change - 1;
StringBuilder builder = new StringBuilder();
builder.AppendLine(@"select * from");
builder.AppendLine("(");
builder.AppendLine("select FIELD_1, FIELD_2,
FIELD_3, FIELD_4, FIELD_5, FIELD_6,
FIELD_7, ");
builder.Append(" row_number() over(order by FIELD_1)
rn");
builder.AppendLine(" from tablename");
builder.AppendLine(")");
builder.AppendLine(string.Format("where rn between {0} and {1}",
from, to));
builder.AppendLine("order by rn");
return builder.ToString();
}
public static void insert(List<Record> l)
{
try
{
foreach(Record r in l)
client.Index<Record>(r, "index", "type");
}
catch (Exception er)
{
string msg = er.Message;
}
}
Wymień 'client.Index' z 'client.IndexMany (..)' i spróbuj ustalić optymalny rozmiar porcji dla wkładki zbiorczej https://www.elastic.co/guide/en/elasticsearch/guide/current/bulk.html#_how_big_is_too_big – Rob
* weź 4-5 dni * ... czy uruchomiłeś i sprawdź, czy migracja 4 milionów wierszy zajmuje 4/5 dni? – Rahul
Funkcja 'ROW_NUMBER()' wpłynie negatywnie na wydajność, a ty będziesz ją uruchamiał tysiące razy. Używasz już 'OracleDataReader' - nie będzie on pobierał wszystkich czterech milionów wierszy na raz, w zasadzie przesyła je po jednej lub kilku naraz. Zamiast tego powinieneś mieć jedno zapytanie, a podczas budowania obiektów "Record", co 100 lub 500 lub 1000 (np. Zachowaj "count", który zwiększa liczbę każdej pętli), zatwierdz je (np. W 'count% 500 == 0'). To musi być wykonalne w ciągu kilku minut, a nie dni. –