Запрос Orientdb-SQL с миллионами вершин вызывает ошибку Java OutOfMemory

Мне нужно создать ребра между всеми вершинами класса V1 и всеми вершинами класса V2. Мои классы имеют 2-3 миллиона вершин каждый. Двойной цикл for с SELECT * FROM V1, SELECT * FROM V2 дает ошибку Java OutOfMemory (heap space) (см. ниже). Это автономный процесс, который будет выполняться один или два раза при необходимости (не частая операция), так как график не будет регулярно обновляться пользователями, только мной.
Как сделать это пакетами (с помощью SELECT…LIMIT или g.getvertices ()), чтобы избежать этого?

Вот мой код:

        OrientGraphNoTx G = MyOrientDBFactory.getNoTx();
        G.setUseLightweightEdges(false);
        G.declareIntent(new OIntentMassiveInsert());

        for (Vertex p1 : (Iterable<Vertex>) EG.command( new OCommandSQL("SELECT * FROM V1")).execute()) 
        {
            for (Vertex p2 : (Iterable<Vertex>) EG.command( new OCommandSQL("SELECT * FROM V2")).execute()) 
            {
                if (p1.getProperty("prop1")==p2.getProperty("prop1")
                {
                    //p1.addEdge("MyEdge", p2);
                    EG.command( new OCommandSQL("create edge MyEdge from" + p1.getId() +"to "+  p2.getId() + " retry 100") ).execute ();
                }
            }
        }
        G.shutdown();

OrientDB 2.1.5 с API Java / Graph

NetBeans 8.1 с параметрами VM-Xmx4096m и-Dstorage.diskCache.bufferSize=7200


Сообщение об ошибке в консоли:

2016-05-24 15:48:06: 112 информация {db=MyDB} [TIP] запрос ‘ SELECT * FROM
V1 ‘ возвращает результирующий набор с более чем 10000 записей. Проверить, если
вам действительно нужны все эти записи, или уменьшить результирующий набор с помощью
Ограничение для повышения производительности и используемой оперативной памяти
[OProfilerStub]java.ленг.OutOfMemoryError: сброс кучи Java
куча в java_pid7896.hprof …

Сообщение об ошибке в выходных данных Netbeans

Исключение в потоке » main»
com.orientechnologies.ориентировать.предприятие.канал.двоичный.OResponseProcessingException:
Исключение во время обработки ответа. на
com.orientechnologies.ориентировать.предприятие.канал.двоичный.OChannelBinaryAsynchClient.throwSerializedException (OChannelBinaryAsynchClient.java:443)
на
com.orientechnologies.ориентировать.предприятие.канал.двоичный.OChannelBinaryAsynchClient.handleStatus (OChannelBinaryAsynchClient.java: 398)
на
com.orientechnologies.ориентировать.предприятие.канал.двоичный.OChannelBinaryAsynchClient.beginResponse (OChannelBinaryAsynchClient.java: 282)
на
com.orientechnologies.ориентировать.предприятие.канал.двоичный.OChannelBinaryAsynchClient.beginResponse (OChannelBinaryAsynchClient.java: 171)
на
com.orientechnologies.ориентировать.клиент.дистанционный.OStorageRemote.beginResponse (OStorageRemote.java: 2166)
на
com.orientechnologies.ориентировать.клиент.дистанционный.OStorageRemote.команда (OStorageRemote.java: 1189)
на
com.orientechnologies.ориентировать.клиент.дистанционный.OStorageRemoteThread.команда (OStorageRemoteThread.java:444)
на
com.orientechnologies.ориентировать.ядро.команда.OCommandRequestTextAbstract.execute (OCommandRequestTextAbstract.java: 63)
на
com.tinkerpop.светокопия.Imps.ориентировать.OrientGraphCommand.execute (OrientGraphCommand.java: 49)
на xx.xxx.xxx.xx.MyEdge.(MyEdge.java: 40) at
xx.xxx.xxx.xx.GMain.main (GMain.java: 60) вызвано:
Ява.ленг.OutOfMemoryError: превышен предел накладных расходов ГК

1 ответ

  1. В качестве обходного пути можно использовать код, похожий на следующий

    Iterable<Vertex> cv1= g.command( new OCommandSQL("SELECT count(*) FROM V1")).execute();
    long counterv1=cv1.iterator().next().getProperty("count");
    
    int[] ids=g.getRawGraph().getMetadata().getSchema().getClass("V1").getClusterIds();
    
    long repeat=counterv1/10000;
    long rest=counterv1-(repeat*10000);
    
    List<Vertex> v1=new ArrayList<Vertex>();
    int rid=0;
    for(int i=0;i<repeat;i++){
        Iterable<Vertex> v= g.command( new OCommandSQL("SELECT * FROM V1 WHERE @rid >= " + ids[0] + ":" + rid  + " limit 10000")).execute();
        CollectionUtils.addAll(v1, v.iterator());
        rid=10000*(i+1);
    }
    if(rest>0){
        Iterable<Vertex> v=g.command( new OCommandSQL("SELECT * FROM V1 WHERE @rid >= " + ids[0] + ":" + rid + " limit "+ rest)).execute();
        CollectionUtils.addAll(v1, v.iterator());
    }
    

    Надеюсь, это поможет.