Qt nagyon lassú SQL query windows alatt

Fórumok

Sziasztok.

Vagy egy Qt-s programom, ami Windows és Linux alá is fordítható.
A programot Linux alatt fejlesztem. tesztelem. Windows alatt vc 2013-vel fordítom 64 bitesre (debuggert a mai napig nem sikerült Windows alá installálni).
Ma szembesültem azzal, hogy a program Windows Server 2012 R2-n irreálisan lassú:
Egy lekérdezés:
SELECT hwaddress FROM (
SELECT DISTINCT(hwaddress) FROM arps
UNION DISTINCT
SELECT hwaddress FROM mactab
UNION DISTINCT
SELECT DISTINCT(hwaddress) FROM interfaces WHERE hwaddress IS NOT NULL
) AS macs ORDER BY hwaddress ASC;
Az eredmény ~100 000 sor, futási idők:
Linux, a programban : ~3 másodperc
Linux, pgadmin III : 4.6 másodperc
Windows, a programban : ~20 másodperc
Windows, pgadmin 4 : 6 másodperc
Ez így nagyon nem kerek. A Windows tényleg egy szerver: Dell PowerEdge R510, egyedül vagyok bejelentkezve RDP-n keresztül. A linux pedig egy közepesen erős asztali PC.
Ötletem sincs hol kéne nézelődni (a windows rendszerekben kevésbé vagyok otthon, azokat nem is én adminisztrálom).

Hozzászólások

Lehet hülyeség, de:
ha mögé teszel egy LIMIT 1-et, akkor gyorsabb lesz?
Ha így is lassú maradna vagy nem javulna sokat akkor nem az sql futtatásánál van a gond, hanem az sql szerver elérésénél, kommunikációnál.

Ha pgAdmin-al futtatom a lekérdezést, akkor nincs olyan nagy különbség, a 6 másodperc sem egy rettenet, és néha lefut hamarabb is, még kisebb különbséggel.
A LIMIT 1 után szinte azonnal lefut a lekérdezés (mivel először elcsesztem a query stringet, a hibaüzenet is azonnal jön).
Ezek szerint a rekordok lekérése, feldolgozása lassú.

Nem kell mind, egy QComboBox widget kapja a listát, és csak az "kell" amit a júzer kiválaszt. Itt pont ki lehet váltani ezt a lekérdezést, akár el is lehet hagyni, de mi lesz a többi query-vel? Máshol nem olyan feltűnő, de egy sokkal gyorsabb vason futnak a lekérdezések sokkal lassabban. Sőt az otthoni gépemen is gyorsabb, pedig az VPN-el csatlakozik a belső hálóra.
Kipróbálom egy másik (virtuális) W2012R2-n.

Lehet, hogy a pgAdmin is csak pár sort kér le, emiatt lesz 6s vs. 20s a különbség.

Valami Postgres konfig okozhatja a jelenséget. Ennél azért jobban kellene érteni az SQL-hez és az adatbázisokhoz általában, pláne ha ennyi adat van benne, azaz nem egy böngésző local storage-áról beszélünk SQLlite-tal.

Meg furcsa a 100e soros eredmény... ezt nem illik egyben megjeleníteni. Lapozással már sokkal gyorsabb lenne.

Az SQL szerver oldali problémának ellentmond, hogy a Linux kliens közel egy nagyságrenddel gyorsabb, még VPN-en keresztül is.
A 100e sor tényleg túlzás,és részben egy hiba eredménye (valamiért nem fut le a hibás/elavult címek törlése), de ez most kapóra jött, mert így kibukott ez a probléma. Eddig is az volt az érzésem, hogy baromi lassú.
Benne van a pakliban az is, hogy a Dell szerverrel van probléma. Előtte egy Win.2012 terminál szerver volt rajta, és az néha olyan volt, mintha egy 9600-as modemmel kapcsolódtam volna rá. A Google kidobott találatokat lassú Dell szerverre, de azok R810-ek voltak.
Eldöntené a kérdést, ha egy másik vason tudnám futtatni a programot, de a másik (virtuális) gép éppen bedőlt, installt meg még nem csináltam a programhoz, így az egy kis idő (ami nem nagyon van).

Na összeraktam (gányoltam) az installt. Egy HP laptop-on (i5-4210U, 4G RAM) nem sokkal jobb a helyzet, kb másfél kétszer gyorsabb mint a Dell szerver, de közel tízszeres lassulással indultunk, így ez még mindig nagyon lassú (Giga bit, kevés hop).
Pár dolgot írhatok át optimálisabbra, bonyolultabbra, és átláthatatlanabbra.
Más: Azt valaki elárulhatná, hol van leírva milyen DLL-ek kellenek a postgresql eléréséhez. Elolvastam egy pár fórumot, bár több helyen is tippelnek, de egy sem jött be. A teljes postgresql installálása sem jött be. Végül az összes DLL-t hozzácsaptam a programhoz, így elindult, De ez így nem tűnik elegánsnak.

Mi koze a Qt-nek az SQL query-hez?

Maskeppen megfogalmazva: konkretan mi a lassu? Merd meg (profiling, de akar "printf debugging"-gal). Onnan lehet tovabbmenni.

Ha csak az nem, hogy egy Qt-ben megírt (multiplatform) programban egy SQL lekérdezés kapcsán derült ki, hogy valami irreálisan lassú.
Vagy az adatok jönnek lassan, vagy a feldolgozásuk lassú.
Windows alól szívesen futtatnák fordításon kívül más okosságokat is, de mint írtam windows-ban nem vagyok annyira otthon, és eddig csak annyi sikerült, hogy le tudom fordítani a programot.

Koncentraljunk a lenyegre: milyen szinu billentyuzeten irtad a programot? Nagyjabol ugyanennyi koze van a konkret SQL lekerdezesednek (ami olyan, amilyen) ahhoz, hogy a Qt mit kezd az eredmenyekkel.

Ehhez kepest olyan aprosagokrol egy szot sem irtal, hogy milyen verzioval forditasz, milyen forditasi opciokkal, esetleg valami konkret programkodot is bemasolhattal volna, ami ezt a query-t meghivja. Az SQL-ed alapjan erdekes disznosagok derulhetnenek meg ki.

Igy latatlanban meg ket dolgot tudok ehhez hozzatenni:

1. http://doc.qt.io/qt-5/qsqldatabase.html#setConnectOptions - talan masok a default beallitasok Windowson, mint Linuxon? Csak egy tipp. Peldaul szokott lenni olyan beallitas, hogy lekerdezes futtatasa utan hany sort prefetch-eljen a memoriaba. De meg azt sem irtad, milyen adatbazist hasznalsz, ezert ennel tobbet nehez mondani.

2. MUKODJ! (Uri Geller utan szabadon)

A billentyűzet fehér (kicsit sárgás árnyalatú :).
Ez egy rövideke kis program: https://github.com/csikfer/lanview2 , ha érdekelnek a részletek (még 60e sor sincs).
A Linux-on a Qt 5.5, a Windows-on 5.8.
SQL: Postgresql 9.5 (virtuális Ubuntu 16.04 / Hyper-V Win 2012 R2 cluster-en).
A "MUKODJ!"-t még nem próbáltam, mert működik, csak a kollégák Windows alól szeretnék, bármelyik (Windows 10) kliens gépről, és a jelenlegi felállásban a rendelkezésre álló Windows 2012 R2 szerveren baromi lassú (mint sejtettem minden nagyobb lekérdezés, nem csak ez).

Erről van szó?
https://github.com/csikfer/lanview2/blob/bef9031544b6dc44d083eb890891b6…

Első körben én megpróbálnám egy QStringList-be berakni az összes mac-et, majd egy lépésben feltölteni a QComboBox-ot addItems-sel, hátha az megoldja a problémádat.*

Ha ez nem segít, akkor QSqlQueryModel-t tudod megpróbálni, és átadni setModel-lel a QComboBoxnak. Elvileg ez tud(hat) olyat, hogy csak annyit töltsön be amennyi kell-látszik, meg ilyenek. Hogy QComboBox-szal működik-e rendesen az kérdés, normális esetben nincs 100e elem bennük, valószínűleg nincs is erre optimalizálva...

*: Igazából mérni kéne, hogy hol lassú: ha debug infoval fordítasz, akkor egy Very Sleepy is elég lehet...

"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee." -- Ted Ts'o

Azért nem semmi, hogy megtaláltad. Néha én is eltévedek benne.
Kicsit lejjebb olvasható: SQL lekérdezés nélkül pontosan ugyan ilyen lassú 100e sor a QComboBox-ban.
Mivel megoldva, hogy Linux alatt futtatva XRDP-n keresztül lehessen használni, részemről felejtős a Windows verzió. Talán a diszpécseri konzollal elszórakozom (ha ráérek), hogy fusson rendesen Windows-al, aztán ennyi.
Át akartam írni a címet, mert egyrészt tévedés, másrészt részemről megoldva, de nem látom hogyan lehet. Ez a lehetőség megszűnt?

Köszi, ezt még "előjegyzem" mint kipróbálandót. Azért én (optimistán) arra számítanék, hogy ha ez a lassulás egy bug miatt van, akkor azt a 4.x -ről 5.8 verzióra ezt kijavítják.
A 100e rekord miatt aggódókat megnyugtatnám, hogy a beütemezett de eddig kifelejtett "clean" rutin után, már csak 7e rekord van.

A keresés csodákra képes. :)

Olvastam a lentit, a feltevésem az volt, hogy az addItem csinál extra dolgokat, a te esetedben 100e alkalommal, amit esetleg az addItems csak egyszer. Mivel a kód eltérés minimális, gondoltam egy próbát megér.

"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee." -- Ted Ts'o

Figyelmetlen voltam, az addItem/addItems cserét csak most próbáltam ki. Már nincs 100e rekordom, de érzésre sokkal gyorsabb, ha egyszerre rakom a widgetbe az elemeket az addItems()-el. (Visszarakva a lekérdezés nélküli tesztet, 100e elem 6 másodperc, több mint 3x-os gyorsulás.)
Van még egy táblázat, ami lassú, ha azon is tudok javítani, akkor nem annyira gáz a Windows verzió.

Talált - süllyedt...
Semmi köze az SQL-hez a válaszidőnek. Ha számokat rakok a widgetbe 1-100000 között, akkor 20 másodperc (SQL-estül meg ugyanennyi).
Itt kihajíthatom a lekérdezést, lehet csak sima szöveges input, nem nagy cucc, de mi a fenét csinálok a többi lassú funkcióval? Az nagyon gáz, ha a Qt majdnem tízszer lassabb Windows-on. Ez ebben a formában csak látszólag multiplatform.

Nagyon regen foglalkoztam SQL-el, igy passzolom hogy az SQL parancsot lehetne-e optimalisabban megirni, viszont a fenti parancsot kiprobalhatnad egy shell-bol vagy az SQL motor parancs ablakaban Qt-t megkerulve. Igy kiderul hogy a Qt a ludas vagy a driver Windowsos implementacioja ennyivel lassabb.

Hát, sem a Qt, sem az SQL (pláne ilyen százezer sorokkal) nem P3-ra lett kitalálva, szóval igen, bloatware mindkettő. Mondjuk nem hinném, hogy a topiknyitó progija konkrétan a Qt miatt lassú. Lehet nem optimálisan van megírva, de nem a Qt lesz a hunyó. Esetleg még a fordításnál lehet a kutya elásva.

1. rémes ez az sql
2. tehát lekérsz 100ezer sort (ez azért nem biztos hogy annyira kevés adat)

én memóriafoglalási problémára, memóriabeállítás-beli különbségre tippelnék a két Qt variáns között
amúgy ha egyszálú a program akkor az újabb asztali pc simán lehet gyorsabb mint a viszonylag régi dell r510.
--
Gábriel Ákos
http://ixenit.com

Mint fentebb írtam nem életszerű a 100e sor, csak egy takarító program nem fut valamiért (ez egy másik történet, ha időt szánok rá bizonyára megoldom).
Ez a 100e sor viszont azt eredményezi, hogy jól mérhetővé válik a lassulás.
Ha a query szar, akkor szívesen fogadom a javaslatokat. A "rémes" az nem javaslat. Itt és most, töredelmesen bevallom, hogy nem értek mindenhez, de szívesen tanulok.

Először jó volna eldöntened hogy mit akarsz.
Ha úgysincs normál esetben 100e sorod, akkor oldd meg, s akkor mindegy lesz mi mennyi idő alatt foglal memóriát, úgysem kell sok.
Ha van 100e sorod akkor meg foglalkozz a memóriafoglalással.

Az SQL azért rémes mert 3 full table scan egymás után nem szokott jót jelenteni (100e sornál).
Ha csak párszáz sor van akkor persze lényegtelen.

Azt hogy ez a 100e sor nem normális még véletlen se a topicnyitóban írtad hanem a hozzászólásom után jóval.

--
Gábriel Ákos
http://ixenit.com

Ki szeretném deríteni, miért lassabb a Windows verzió a linux-osnál. A 100e sorrol meg akadjunk már le, teljesen irreleváns a probléma szempontjából.
Ha az a feladat, hogy kapjunk egy listát, jelenleg az ismert MAC címekről, amik három táblából jönnek össze: a bejegyzett gépekhez tatozó interfészek MAC-jei, az ARP táblák lekérdezéséből keletkezett arps táblából, valamint a switch-ek címtábláinak lekérdezéséből keletkező mactabs táblából. Ha jól értem, a Te javaslatod, hogy ilyen listát egyáltalán ne is akarjak. Lehetőség, hogy írok egy pár ezer soros kis modult, hogy ez optimálisabb legyen, és ne keljen ilyen lista, de ha lejön (le kéne jönnie) 3 másodperc alatt, akkor nem fogok hetekig kódolni. Vagy hagyom a francba az egészet, írja be a címet egy text-be, és majd kiderül, hogy jót írt-e be.

Ha venned a faradsagot es bemasolnad ide mondjuk az adatbazis semadat nehany alapadattal (pl. melyik tablaban hany sor van), biztosan lenne par fanatikus, aki percek alatt szetoptimizalna a query-det (es a semadat) neked, aminek ket eredmenye lenne:

1. a lekerdezesed 3 masodperc helyett 3 tizedmasodperc alatt futna le, de legalabbis produkalna megjelenitheto eredmenyt

2. tanulhatnal belole.

Sajnalom, hogy idaig nem sikerul eljutnod.

Nem jól érted. A javaslatom az, hogy három külön selecttel képezd a listát és kliens oldalon rakd össze.
A bejegyzésed többi része eléggé cinikus, asszem.

Én ha a lassúság okát keresném, akkor a következőt tenném:

- psql-ből a szerveren futtatnám a query-t, hogy annak mennyi a nettó ideje van ugye a \t (esetleg explain-el)
- (ha már itt vagyok, megnézném hogy a 3 query külön mennyi idő)
- megnézném a hálózat áteresztőképességét, nem az lassú-e, iperf, ftp, akármi
- qt-ben csinálnék nagyobb tömböket (kb mint az adatmennyiség amit át akarsz hozni), feltöltve nullákkal, hogy ennek is megmérjem a nettó idejét

Nyilván nem egy mérést csinálnék, átlagolnék, a szélsőértékeket kihagynám, stb.
Ebből láthatónak kéne lenni hogy hol az eltérés.

--
Gábriel Ákos
http://ixenit.com

Nem láttam még Windows alatt gyorsan működő Qt-s programot. Linux alatt valamivel jobb a helyzet, de ott is igaz az alábbi.

Memóriazabáló, CPU éhes bloatware az egész Qt úgy, ahogy van.

Csak lusta fejlesztők használják, akik sajnálják az időt normális kódot írni, normális library-kkel.

Ezek alapján én nem fogom tudni megmondani, hogy mi lassú, de egy két tippet lehet tudok mondani. Egyrészt a 100e sor adat az nem GUI -ba való, legalábbis nem egy az egyben. Ha le is kérdezed akkor lehet nem kellene egyben megjeleníteni őket. Nekem volt régebben olyan jellegű gondom, hogy egy QListView már 10e elemnél is hirtelen elkezdett belassulni, néha még fagyott is. A Qt alatt lévő kódok amik az ablakozó felületekben lévő gui-t hajtják mások linuxon és windowson, és a rendszer is (nyíván) más ami az adatokat megjeleníti. 100e sornál ha a windowsos combobox csak egy sorba rendezést is elindít, amit a linuxos nem, akkor már okozhatja ezt a gondot.

Régebben amikor mindenképp ennyi adatot akartam megjeleníteni egy táblázatban saját listázót kellett írjak ami képes volt azt gyorsan zökkenőmentesen megjeleníteni.

Annyi tippem lenne még, hogy a programodba vedd fel az egyik átalam írt lib http://hyperprog.com/gsafe/index.html kódjából kihalászott dconsole.h és dconsole.cpp fájlokat. (Semmi függőségük nincs, elég ha bedobod őket a project-be) Ha bárhol a programodban meghívod a dconsole(); függvényt a programoddal egy szinten megjelenik egy konzol ablak (Kb ilyen: http://hyperprog.com/gsafe/doc/html/pictures_doc/hdebugconsole.png) amiben a programod által létrehozott SQL környezeten belül tudsz sql parancsokat lefuttatni. Ha ebbe belenyomod a lekérdezést hamar kiderülhet, hogy a kapcsolattal van gond, vagy a gui-val, és LIMIT -ek segítségével meg kitapasztalhatod, hogy ez kb hány sor adatnál kezdődik.