Jump to content
php.lv forumi

union all optimizēšana lielām tabulām


Swear

Recommended Posts

Ir divas tabulas ar gandrīz vienādiem laukiem.

 

tabula1: id, laiks, dati;

tabula2: zid, laiks, dati;

 

iekš tabula1 ir dati:

1, 123456, dati;

3, 123456, dati;

6, 123456, dati;

 

iekš tabula2 ir dati:

2, 123456, dati;

4, 123456, dati;

5, 123456, dati;

 

id katrā tabulā ir unikāli. ir nepieciešams izvilkt visus datus un apstrādāt oderdojot pēc id desc.

izmantoju šādu kveri:

SELECT * FROM tabula1 UNION ALL SELECT * FROM tabula2 order by id desc

 

problēma ir tikai tāda ka kopā starp abām tabulām ir 35k ieraksti, tādēļ šis kveris izpildas >2sec.

 

Jautājums - kādu alternatīvu izmantot, kā optimizēt to kveri, vai arī kā kešot datus lai samazinātu izpildes laiku?

Link to comment
Share on other sites

Nu pirmajā tabulā tiek uzglabāti derīgi dati, tad kad šiem datiem beidzas termiņš viņi tiek pārvietoti uz otru tabulu. Pirmajā tabulā jābūt tikai derīgiem datiem lai meklēšana būtu pēc iespējas ātrāka.

 

Laigan salīdzinot select kverijus starp abām tabulām laika zudums ir diezgan niecīgs.

tabula1: Query took 0.0089 sec

tabula2: Query took 0.0446 sec

 

Visticamāk šāds princips (pārvietot nevajadzīgos datus uz citu tabulu) vairs nav aktuāls, jo tas ir 6 gadus vecs skripts, kad, laikam, datu select`ošana bija stipri ne-optimizētāka.

laikam tomēr būs jāizmanto viena tabula :]

Link to comment
Share on other sites

Nu izveido skatu, pamēģini tad atlasīt. Skats ir kā virtuāla tabula, ko tu nodefinē pats pēc vajadzīgā kvērija.

Skaties tikai, jo skats neatjaunojas pats no sevis, ja mainās orģinālajās tabulās dati. (visdrīzāk ir jāpievieno kāds nosacījums, kad tiek atjaunoti skata dati)

Link to comment
Share on other sites

Nevar apvienot visu vienā tabulā?

 

EDIT: cits variants varētu būt lietot skatus (VIEWS), bet tas ir jāpārbauda, vai būtu uzlabojums atlases ātrumā.

 

tas neko nedos, view izpildīs beigās to pašu query. un tas par datu atjaunošanu arī nebūs taisnība.

Link to comment
Share on other sites

problēma ir tikai tāda ka kopā starp abām tabulām ir 35k ieraksti, tādēļ šis kveris izpildas >2sec.

 

Jautājums - kādu alternatīvu izmantot, kā optimizēt to kveri, vai arī kā kešot datus lai samazinātu izpildes laiku?

nepareizi nevis 35K ierakstu bet 35K*35K ierakstu , attieciigi meklesanas laiks ir liels...

neizmanto pilno apvienosanu ( UNION, bet gan selektiivo JOIN [ INNER JOIN .... vai citu ], piedevaam uzreiz atlasi tikai derigos datus...

Link to comment
Share on other sites

Ko nozīmē apstrāde?

Ja visu ierakstu (kopā saprotu, ka 35K, kas patiesību sakot ir pupu mizas) apstrāde notiek reti,tad kuru uztrauc tās 2 sekundes, piem, pāris reizes diennaktī?

Savukārt, ja VISUS ierakstus ir jāapstrādā bieži, tad kas ir tas par tādu dīvainu procesu un biznesa nepieciešamību, ka ik pēc maza laika jāizgriež cauri visus datus?

 

Te vispirmām kārtām vajadzētu saprast kā un kāpēc ir organizēts process un ko vajag panākt un tikai tad ķerties pie darbiem.

 

Gints Plivna

http://datubazes.wordpress.com

Link to comment
Share on other sites

Loģika tiešam pieklibo, sadala divās tabulās, lai it kā būtu ātrāk, bet pēc tam join'o kopā, lai iegūtu n-reizes lēnāku risinājumu. Kaut ko es nesaprotu. 75K jau nav tāds apjoms, lai būtu problemas visu turēt vienā tabulā.

Link to comment
Share on other sites

nepareizi nevis 35K ierakstu bet 35K*35K ierakstu , attieciigi meklesanas laiks ir liels...

neizmanto pilno apvienosanu ( UNION, bet gan selektiivo JOIN [ INNER JOIN .... vai citu ], piedevaam uzreiz atlasi tikai derigos datus...

UNION jau nu gan netaisa 35k x 35k ierakstu saitu, savukārt pliks JOINS tieši taisa 35k x 35k ierakstus.

 

Šeit viennozīmigi normāls risinājums ir likt vienā tabulā un datīt tākā dagrevis teica.

Liekam lauku actual un liekam indeksu uz actual, whatever_field_for_orderby_or_search un viss strādās griezdasmies.

Link to comment
Share on other sites

Šeit viennozīmigi normāls risinājums ir likt vienā tabulā un datīt tākā dagrevis teica.

Liekam lauku actual un liekam indeksu uz actual, whatever_field_for_orderby_or_search un viss strādās griezdasmies.

Te kaut kas nelīmejas kopā.

Ja vajag meklēt/apstrādāt tikai jaunākos/aktuālos ierakstus, tad kāda mārrutka pēc tur būtu jālieto UNIONS, ja speciāli jaunākie dati ir tikai VIENĀ NO TABULĀM, un kā es saprotu no postētāja, ne jau meklēšanā ir problēma.

Problēma ir kaut kādā mistiskā apstrādē "izvilkt visus datus un apstrādāt oderdojot pēc id desc.

izmantoju šādu kveri:"

Un es personīgi nesaprotu pat pie šo 2 tabulu situācijas, kāpēc šāda apstrāde ir problemātiska un kā 1 tabula šai gadījumā būtiski palīdzēs?

 

Jo pat, ja šos datus iebāzīs 1 tabulā, kopējais nolasāmais ierakstu daudzums diez vai samazināsies, ja apstrādes loģika nekā netiks mainīta, vienīgais ko mēs iegūsim, tas ir, ka MySQL nebūs jāapvieno abu tabulu dati un tie pēc tam jākārto, bet to varēs darīt uzreiz kaut vai pēc PK indeksa. Ja vien dzelzis nav kaut kāds pilnīgi no akmens laikmeta, vai iespējams MySQLs sakonfigurēts tā lai tam atmiņa būtu daži K (nezinu vai tā var izdarīt), tad ieguvums būs tuvu 0. Manuprāt, lielākā bremze jebkurā gadījumā būs šos 35K ierakstus nolasīt un "apstrādāt", lai ko tas arī nenozīmē, nevis apvienot un sakārtot no 2 tabulām.

 

Gints Plivna

http://datubazes.wordpress.com

 

P.S. Tas ko ar visu šo penteri gribēju pateikt - ka 2 tabulas ir diezgan sviestaini, bet apvienojot datus vienā un nemainot šo "apstrādes" loģiku (atlasīt visus datus), diez vai būs kāds vērā ņemams ieguvums.

Edited by Gints Plivna
Link to comment
Share on other sites

Viņš taču visu jau uzrakstīja pirmajā postā.

2 tabulas, viena ar aktuāliem datiem, viena ar veciem, pieņemu ka lielākajā daļā gadījumu viņš strādā tikai ar jaunajiem datiem

bet kaut kādā vietā ir nepieciešami abi dati, līdz ar to viņs taisa union kārto pēc id un atlasa ar limit, visdrīzāk kādā lapaspušojamā lapā.

Problēma viņām ir tāda, ka pieprasot jebkurus 20 ierakstus, viņam ir jātaisa pilns abu tabulu unions, jākārto šie dati un tad ar limit, offset jāatlasa.

 

Ja viņš glabātu visus datus vienā tabulā un izmantotu papildus lauku actual, kurš nosaka, vai dati ir aktuāli un uzliktu indeksu uz actual, id, tad šī union kverija vietā viņš varētu pieprasīt vienkārši:

SELECT * FROM tabula LIMIT x,x

viss notiek ātri, jo izmanto primāro atslēgu: id.

 

kamēr pārējo kveriju, kur vajag tikai aktuālos datus, atlasīšanai, var izmantot šo indeksu un pieprasīt

SELECT * FROM tabula WHERE actual=1 ORDER BY id LIMIT x,x

Viss notiek ātri, jo izmanto indeksu: actual, id

 

 

P.S. Protams, ja topika autors precīzāk aprakstītu to, ko viņš grib izdarīt ar datiem, nevis ar pašu datu bāzi, tad tauta noteikti nāktu ar daudz precīzākiem risinājumiem.

Edited by codez
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
×
×
  • Create New...