mff-uk / odcs

ODCleanStore
1 stars 11 forks source link

Browse/Query really slow for localRDF intermediate storage #886

Closed tomas-knap closed 10 years ago

tomas-knap commented 10 years ago

Go to ODCS, open exec monitor detail with id 674, go to browse/query, and try to browse data, e.g. for gov-cz:Organy. You can wait minutes and no data appear. What is the reason for that? It seems that data are lazy loaded, so I would expect to see first 30 triples really quickly. What is the problem? what are the queries being executed to the DB? Ask Petr to help you tuning the queries if they are suspicious.

This is a problem, becuse browse/debug is are core feature and it cannot be used properly.

I am using localRDF repo currently.

tomas-knap commented 10 years ago

Please test the browse working with couple of milions of triples. It should be possible because of the lazy loading. Ask Jirka (@tomesj) how to generate 7 milions of triples

bogo777 commented 10 years ago

We talked about this, we are lazy loading data, but we need the total count triples to show total pages. And count function for CONSTRUCT is really slow, especially for localRDF. From what I got from looking to source, we are iterating through all triples(see BaseRDFRepo, method getSizeForConstruct() ). I think any improvement should be made there.

tomesj commented 10 years ago

If you want show only total pages - for browsing all data in graph (construct query like CONSTRUCT {?x ?y ?z} WHERE {?x ?y ?z } - call method getTripleCount().

tomesj commented 10 years ago

I updated method using only in last version - it could be faster :-)

tomas-knap commented 10 years ago

Jirka, please test that - run the pipeline with 7milions of triples and native store in debug mode and then try to browse. The method on count could take < 1s, so I would expect the first results in the browser in < 1s. Please report here.

tomesj commented 10 years ago

So I tried browse on the large collection (7 milions triples)

tomas-knap commented 10 years ago

Thanks, why does it take 8s first time? What is the reason for that?

tomas-knap commented 10 years ago

@bogo777 do you have any clarification why it is much slower first time?

bogo777 commented 10 years ago

I don't. I will add some logging, so we see, where it spends this time.

@tomesj Could you give me the guide how to generate 7 milion triples?

tomesj commented 10 years ago

@bogo777 The simples way how to get graph with 7 milions triples: 1) Download file with 7 milions triples / or something size like this 2) Load this file in your concrete named graph through Virtuoso conductor -> Linked Data ->Quad Store Upload

I actually don´t have this file on my disk yet, only graph in Virtuoso,

But you can used file like this: 9,8 mil triples http://www.cs.toronto.edu/~oktie/linkedct/linkedct-dump-2009-03-10.nt

Or see page for large RDF data collection and download file about size you need: http://www.w3.org/wiki/DataSetRDFDumps

tomas-knap commented 10 years ago

Bohuslave, pro ty data, napis si pipeline se SPARQL extractorem, ktera stahne nejaka vetsi data. Inspiraci muzes brat tu: http://linked.opendata.cz/ Je tam seznam datasetu, i s prislusnym named graph, ktery zadas do konfigurace SPARQL extractoru. Adresa SPARQL extractoru je http://linked.opendata.cz/sparql

tomas-knap commented 10 years ago

Vystup extraktoru pak zkus zobrazit v browseru. Pro zjisteni poctu triplu v datasetu: klikni na dataset na linked.opendata.cz a dostatnes statistky

bogo777 commented 10 years ago

Zkusil jsem 5 extractorů z různých grafů z linked.opendata.cz, ale ač ukazují, že mají přes milion triples, tak se mi jich vždy extrahuje jen 10001. A výsledný graf, který má 50005 triples přes conductor, tak v Browse/Query ukazuje 667 stran * 15 triple na stránku = opět jen 10000 triples. Předpokládám, že problém je někde na naší straně? Je potřeba někde něco nastavit?

tomas-knap commented 10 years ago

10000 byva standardni limit poctu vracenych records ve virtuoso.ini pro praci se SPARQL. Zvedni si jej. Nebo pouzij localRDF misto virtuosa

bogo777 commented 10 years ago

I have about 5M triples and it acts little strange. Sometimes it is extremely slow(propably due to RAM), then it takes several seconds and sometimes it is very fast(possibly caching). I added logging when calling RDF queries, so please test it yourself. In any case, it is always stuck on the RDF method(size/data) query, so there is no delay in frontend code.

For first query there is this in the log: 12:33:10.849 [http-bio-8084-exec-25] DEBUG c.c.m.x.o.f.c.rdf.RDFQuery - Size query started... 12:33:10.962 [http-bio-8084-exec-25] DEBUG o.o.r.DatatypeHandlerRegistry - Registered service class org.openrdf.rio.datatypes.XMLSchemaDatatypeHandler 12:33:10.964 [http-bio-8084-exec-25] DEBUG o.o.r.DatatypeHandlerRegistry - Registered service class org.openrdf.rio.datatypes.RDFDatatypeHandler 12:33:10.965 [http-bio-8084-exec-25] DEBUG o.o.r.DatatypeHandlerRegistry - Registered service class org.openrdf.rio.datatypes.DBPediaDatatypeHandler 12:33:10.967 [http-bio-8084-exec-25] DEBUG o.o.r.DatatypeHandlerRegistry - Registered service class org.openrdf.rio.datatypes.VirtuosoGeometryDatatypeHandler 12:33:10.969 [http-bio-8084-exec-25] DEBUG o.o.r.DatatypeHandlerRegistry - Registered service class org.openrdf.rio.datatypes.GeoSPARQLDatatypeHandler 12:33:10.976 [http-bio-8084-exec-25] DEBUG o.o.r.LanguageHandlerRegistry - Registered service class org.openrdf.rio.languages.RFC3066LanguageHandler 12:34:07.113 [http-bio-8084-exec-25] DEBUG c.c.m.x.o.f.c.rdf.RDFQuery - Size query finished!

It may be that 7 seconds difference Jirka wrote about.

tomas-knap commented 10 years ago

Jirko, hod sem prosim ten query, kterym zjistujes ten pocet zaznamu

tomas-knap commented 10 years ago

The problem which should be solved is why query on count of triples is sometimes very slow

tomesj commented 10 years ago

Pokud se jedná o zjištění všech záznamů v kolekci - (tedy dotaz např. CONTSTRUCT {?x ?y ?z} WHERE {?x ?y ?z} ), volá se rovnou metoda - connection.size(), která vrací počet všech záznamů

Pro select se položí dotaz typu SELECT (count(*) as ?pocet) WHERE {....} a ten počet se vrátí jako výsledek... Pro nějaký obecný jinak omezený contruct dotaz - na základě contruct dotazu se vytvoří graf - ten se předá modelu a na tom se zavolá metoda size() - která vrátí velikost :-)

tomas-knap commented 10 years ago

"Pokud se jedná o zjištění všech záznamů v kolekci". Ok a cim se lisi ten pripad "Pro nějaký obecný jinak omezený contruct dotaz - na základě contruct dotazu se vytvoří graf - ten se předá modelu a na tom se zavolá metoda size() - která vrátí velikost :-)"?

"Pro nějaký obecný jinak omezený contruct dotaz - na základě contruct dotazu se vytvoří graf - ten se předá modelu a na tom se zavolá metoda size() - která vrátí velikost :-)"

Aha, ale to prakticky znamena, ze zkonstruujes vysledek dotazu a pak spoctes triples? To neni dobre. To je pak lazy querying k nicemu, ne?

tomesj commented 10 years ago

Tak když máš construct dotaz, tak ten vždycky vrací nějaký graf a když chceš zjistit velikost, tak není jiná možnost než to dát modelu a zavolat metodu size.

Neboť samotný graph tuto funkci nemá a kdybys jí chtěl naimplementovat ručně, musel bys vzít všechny ty trojice, které dostaneš, projít je a spočítat kolik jich je, což by nebylo moc dobré.

Nebo víš o nějaké jiné metodě ? Nemůžeme bohužel kombinovat SELECT A CONSTRUCT a zjistit tak velikost třeba jedním dotazem, což by bylo optimální :-)

Co já vím, tak jde jen o získání celkového počtu trojic pro daný dotazy - samotné trojice se pak načítají lazy způsobem, tedy ten je zachován :-)

tomas-knap commented 10 years ago

To jo, ale blbe je, ze v podstate musis vsechny trojice nacist u constructu do pameti abys ziskal jejich pocet, ne?

tomesj commented 10 years ago

Ne, ty dostaneš jako výsledek constructu instanci grafu, takže se drží jen tato instance. Jen tuto instanci dáš modelu a dostaneš instanci modelu s istancí grafu a na ní zavoláš metodu. Myslím, že to není tak, že by se v tom grafu drželi všechny trojice - bude to taky implementované lazy, tedy načtou se, až je skutečně potřeba. Kdyby jsi třeba zavolal iterator na tom grafu pro jejich procházení, nebo něco podobného...Jinak podle mě v paměti místo nedrží.

tomas-knap commented 10 years ago

Jirko, popis prosim na wiki postup, tedy hlavne me zajimaji ty dotazy, kterym se zjistuje kolik bude vysledku na obecny CONSTRUCT. Udelej to prosim do zitrka.

tomesj commented 10 years ago

Tak sepsáno https://grips.semantic-web.at/display/LOD2/Size+of+query+result

Jinak v vlastní dotaz používáme v podstatě jen pro SELECT, všude jinde už voláme metody openRDF sesame.

tomas-knap commented 10 years ago

Jirko, okomentoval jsem na confluence, pri model.size se musi nejprv nacist vsechny triples.

tomas-knap commented 10 years ago

Udelal bych aspon to, ze bych po stisknuti tlacitka browse, nevolal CONSTRUCT, ale SELECT ?s ?p ?o WHERE {?s ?p ?o}. Samozrejme ten select musi pracovat jen na prochazenou data unit. Tim padem se pouzije efektivnejsi varianta prochazeni, navic je mozne filtrovat.

V pripade describe se primo vola SPARQL DESCRIBE?

tomas-knap commented 10 years ago

u SPARQL constructu si holt uzivatel pocka. Pripadne by mel pouzit u constructu spis query and download.

tomesj commented 10 years ago

Co se týká procházení všech trojic, tam se volá metoda size() přímo na repozitáři (RepositoryConnection) nikoliv na modelu a volá se přímo :-) Myslím, že SELECT nebude rychlejší, ale klidně to tak můžu předělat, jestli chceš.

See http://openrdf.callimachus.net/sesame/2.7/apidocs/org/openrdf/repository/RepositoryConnection.html#size(org.openrdf.model.Resource...)

Co se týká DESCRIBE, tak pro zjištění počtu to funguje jako u CONSTRUCTu nebo výsledkem dotazu DESCRIBE je GRAF stejně jako u CONSTRUCTU. Tedy obě používají i stejnou metodu, jen s jinými parametry :-)

tomas-knap commented 10 years ago

Depends on the implementation of repository.size(), but probably yes.

Co se tyce toho selectu, proc vlastne ten count pocitame jako:

http://my.dc SELECT (count( * ) AS ?selectSize) WHERE { SELECT ?x, ?y WHERE {?x dc:has ?y} }?

Vzdy by slo vzdy nahradit v originalnim selectu tu cast pred WHERE tim "SELECT (count( * ) AS ?selectSize)", ne? Samozrejme by to chtelo konzultaci s dokumentaci.

tomas-knap commented 10 years ago

Ale je pravda, ze ne vzdy. Problem by mohl byt kdyz bychom meli napriklad {Select ?s ?p ?o WHERE {} } UNION { Select ?s ?p ?o WHERE {} }

tomas-knap commented 10 years ago

ok, tak to nech, jak to mas, jen prosim zkus pro moji informaci porovnat ty dve varianty pro browse, tedy:

  1. CONSTRUCT {?s ?p ?o} where {}
  2. SELECT (count( * ) AS ?selectSize) WHERE { SELECT ... }

Zkus to prosim na vetsich datech, trebas na tom 7milionovem ;)

tomesj commented 10 years ago

Dobře :) Zkusím to porovnat a rovnou tam dám to rychlejší :-)

tomas-knap commented 10 years ago

Kdyztak zatim jen porovnej a pak rozhodneme

2013/12/20 Jiøí Tome¹ notifications@github.com

Dobøe :) Zkusím to porovnat a rovnou tam dám to rychlej¹í :-)

Reply to this email directly or view it on GitHubhttps://github.com/mff-uk/ODCS/issues/886#issuecomment-31007682 .

tomesj commented 10 years ago

Tak jsem si pro všechny grafy ve Virtuosu zavolal obě metody pro zjištění všech prvků v kolekci a měřil u nich časy.

Výsledek: Pro grafy s velikostí do cca 2000 prvků je lepší použít přímý přístup ( místy je rozdíl až o 50 ms), naopak pro větší grafy je lepší použít SELECT přístup, (většinou je rozdíl v rozmezí do 30 ms)

tomas-knap commented 10 years ago

Tak tam dej ten select. Zoptimalizuj to prosim jeste tak,ze si vzdy zjistis, jestli je v tom dotazu jediny prikaz "SELECT". Pokud ano, tak postupuj dle 1. Pokud je tam vice "SELECTU" v originalnim dotazu (to nebude caste), tak bys pouzil stavajici pristup pro SELECT.

  1. nahradis puvodni dotaz novym nasledovne:

SELECT ma vzdy tvar: SelectClause DatasetClause* WhereClause SolutionModifier, DatasetClause vzdy zacina FROM, ale neni povinna, tedy:

-pokud je tam FROM: nahradis SELECT xxx FROM ... tim SELECT (count( * ) AS ?selectSize) FROM ... -pokud tam neni FROM: nahradis SELECT xxx WHERE ... tim SELECT (count( * ) AS ?selectSize) WHERE ...

Kdyztak koukni na http://www.w3.org/TR/sparql11-query/#rSelectClause

Vyhoda je, ze v tomhle pripade bys mel byt vyrazne rychlejsi nez doted (neb ted vlastne konstruujes cely select a az pak pocitas count nad vysledkem).

tomas-knap commented 10 years ago

a Browse bude potom pouzivat select

tomesj commented 10 years ago

OK, instrukce jsou mi jasné :-) Takže to tak udělám :-) Tím bychom měli dosáhnout ideální optimalizace :-)

tomesj commented 10 years ago

Tak jsem optimalizoval výpočet size ty SELECT queries, jak bylo popsáno :-)

Jinak co se týká procházení všech dat v kolekci - používá se pro zjištění velikosti nyní metoda getResultSizeForDataCollection (založená na SELECT dotazu).

V rámci aplikace browse/query se ale zobrazuje stále dotaz CONSTRUCT {?x ?y ?z} WHERE {?x ?y ?z} neboť pro následné načítání prvků do lazy collection je lepší (výše popsaná metoda založená na selectu jen vrací počet).

Zkoušel jsem a funguje to dost dobře. Dosáhli jsme opět zrychlení :-)

tomas-knap commented 10 years ago

Diky, jake je to zrychleni? 10% nebo 300%?

Ja bych pouzil ten select misto constructu pro browse - tedy pokud to zobrazeni dat trva zruba stejne. Duvod je ten, ze vysledek selectu se da filtrovat

tomesj commented 10 years ago

Zrychlení je cca 10% Jinak já právě zkoušel použít ten select místo contructu i pro přidávání do containeru, ale bylo to hrozně pomalé. (přitom logicky dotaz na velikost je stále stejně rychlý). Možná se tam něco přidává neefektivně, ale to je spíš na Bohuslava.

Proto se nejlépe na browse hodí varianta construct dotaz (select dotaz pro zjištění počtu). Můžu to klidně předělat i na ten select, aby se dalo filtrovat, ale bude to znatelně pomalejší.

tomas-knap commented 10 years ago

Pockej, to je divne. Bych cekal vetsi zrychleni. Zkusim na to kouknout.

@bogo777 netusis proc je SELECT ?s ?p ?o WHERE {?s ?p ?o } znatelne pomalejsi nez CONSTRUCT {?s ?p ?o } WHERE {?s ?p ?o }?

tomas-knap commented 10 years ago

Je potreba vyresit:

Problém je, že pro [1] aktuálně počítáme špatně velikost dle #886, neboť má to jen 1 select - nemá FROM, ale má to WHERE

uděláme z toho SELECT (count(*) AS ?selectSize) WHERE { GRAPH ?g {?x ?y ?z}} tedy zanedbá se to DISTINCT, což se v původním případě nedělo.

tomas-knap commented 10 years ago

Navrhuji rozsirit logiku takto:

Je-li v puvodnim SELECTu DISTINCT, tak se takovy dotaz neda optimalizovat a postupuje se jako v pripade, ze je tam vicero selectu.

tomesj commented 10 years ago

Dobře, rovnou to tak naimplementuji :-)

tomas-knap commented 10 years ago

pozor ze distinct muze byt velkym i malym pismem

tomas-knap commented 10 years ago

teoreticky i jako DistincT

tomesj commented 10 years ago

Tohle mám všeobecně podchycené :-)

tomas-knap commented 10 years ago

Tak je to komplikovanejsi, viz napriklad dotaz: SELECT (count(*) as ?x) WHERE {?s ?p ?o} LIMIT 1000

Tak prosim pro ted zakomentuj to tvoje vylepseni a nech tam tu puvodni variantu, tedy SELECT (count(*) as ?x) WHERE { SELECT {} }. Tedy necht se to vzdy chova jako by tam bylo vic SELECTU, tedy tak jak se to chovalo driv. Pardon ;)

tomesj commented 10 years ago

Dobře - vrátím to tedy zpět na původní variantu :-)

tomesj commented 10 years ago

Vrácené zpět na původní verzi pro výpočet v případě selectu. Tím bych to asi uzavřel :-)