Jump to content
php.lv forumi

Gints Plivna

Reģistrētie lietotāji
  • Posts

    472
  • Joined

  • Last visited

Everything posted by Gints Plivna

  1. Mhmmm cik nu man zināms, tad distinct ir ļoti normāls keywords kurš tā kā +- visur arī ir pieejams. OKZ tātad sākam, ka MySQLā tas ir, Oracle, MS SQLā, Postgresā arī, citos man bija slinkums skatīties, es te googlā atradu kaut kādu it kā SQL92 standarta draftu http://www.contrib.andrew.cmu.edu/~shadow/sql/sql1992.txt kurā arī DISTINCT ir iekšā. Gints Plivna http://datubazes.wordpress.com
  2. Yeahh negribās jau kasīties, bet tas kas tur ir rakstīts par Oracle "iepriekshpeedeejo sekvenci un aiznaakosho sekvenci:" ir nepareizi. Tas ko var uzzināt ir to, kāda pēdējā sekvences vērtība tika izselektēta šai sesijā (ja tāda līdz šim šai sesijā nebija iegūta, tad būs kļūda) ar <seq_name>.currval un nākošo unikālo vērtību ar <seq_name>.nextval. Un VISS. Nav nekādas iepriekšpēdējās vērtības, nav nekādas aiznakošās vērtības. Tas kas tur ir rakstīts par lasīšanu no user_sequences ir nākošā vērtība, kas tiks ņemta tad, kad būs paņemtas visas iekešotās vērtības. Un pat, ja sekvence ir definēta ar atribūtu NOCACHE, tad vienalga vispārīgā gadījumā vairāklietotāju sistēmā nav absolūti nekādas garantijas, ka kāds to sekvences nākošo vērtību jau nebūs pagrābis starplaikā starp manu vaicājumu no user_sequences un nākošo <seq_name>.nextval izsaukumu. Gints Plivna http://datubazes.wordpress.com
  3. A šitāds neder? (Neko nerubīju no MySQLa tāpēc tāds jautājums :) select * from ( select * from tabula order by id desc limit 1,5 ) order by id asc Gints Plivna http://datubazes.wordpress.com
  4. LIMIT 1, 5 neder? Bez where klauzas, bet ar order by klauzu pēc id, timestampa vai jebkāda cita lauka ar ko var noteikt secību. Gints Plivna http://datubazes.wordpress.com P.S. daži jau pasteidzās :)
  5. Mhmmm, es būtu ļoti piesardzīgs lietojot tādus vārdus kā "vienmēr" un "labāks" nepasakot ne precīzi par ko iet runa ne arī ar ko tiek uzskatīts "labāks"... ;) Gints Plivna http://datubazes.wordpress.com
  6. Starp citu nedaudz padomāju, ko nozīmē vārds skalārs un ko vektors, un sapratu, ka pats nosaukums jau vien saka, ka atļauta ir tikai viena vienīga vērtība :) Gints Plivna http://datubazes.wordpress.com/
  7. Šis ko Tu vēlies dabūt saucās skalārie apakšvaicājumi (scalar subquery) un tie var atgriezt tikai vienu vērtību. Šis apakšvaicājumu veids ir aprakstīts šeit http://dev.mysql.com/doc/refman/5.1/en/sca...subqueries.html Tur tā īpaši uzsvērts nav, ka var būt tikai viena vērtība, bet acīmredzot tā tomēr ir. Tā kā es vairāk kaut ko sajēdzu no Oracle, tad tur ir analogi, kas ir aprakstīti šeit http://download.oracle.com/docs/cd/B19306_....htm#sthref2680 Un Oracle aprakstā ir rakstīts apmēram tas pats, tikai uzsvērts, ka "A scalar subquery expression is a subquery that returns exactly one column value from one row". Gints Plivna http://datubazes.wordpress.com
  8. SELECT tb2.name, tb1.id FROM tb1, tb2 WHERE tb1.id = tb2.id UNION ALL SELECT tb3.name, tb1.id FROM tb1, tb3 WHERE tb1.id = tb3.id tb4.id varētu tā kā izmantot auto_increment, es pieņemu, ka nav svarīgs idu sakārtojums? Gints Plivna http://datubazes.wordpress.com
  9. Jā šis protams ir vērā ņemams arguments, bet kā jau teicu 1) jāpārliecinās kas strādā ātrāk un par cik 2) esmu gatavs pieņemt, ka atsevišķos gadījumos pilnībā apzinoties sekas :) ir iespējams attālināties no visādiem likumiem, jo likumi jau tāpēc ir, lai tiem būtu izņēmumi :) BET kā jau teicu ir jāapzinās sekas, un jāsaprot kādas prasības šeit būs un kādas nebūs, un kā mēs tās varam realizēt gadījumā A un gadījumā B. Nu principā indeksi strādā tad, ja ir jāatlasa relatīvi maz datu no tabulas. Šeit faktiski nav īsti skaidrs cik daudz datu no tabulas tipiskā gadījumā būs jāatlasa un varbūt var gadīties, ka full skans būs izdevīgāks. Bet atkal šī ir teoretizēšana, es priekšroku dotu praktiskam eksperimentam. Pie tam ja šādi vaicājumi būs ļoti bieži var sanākt, ka neviena no šīm struktūrām nestrādās pietiekami ātri. Iespējams ir vērts padomāt par kaut ķadu atvasinātu struktūru, kurā ir saskaitītas visas atbildes griezumos pa visiem jautājumiem vai tml. Tas viss protams ir atkarīgs no biznesa prasībām, iespējams, ka potenciālās vēlmes ir tik dinamiskas/neprognozējamas vai arī vaicājumi notiek relatīvi reti un nekādas atvasinātas struktūras neatmaksājas uzturēt. Gints Plivna http://datubazes.wordpress.com
  10. Nu principā jau šādas diskusijas vislabākais tiesnesis ir misters eksperiments ;) Tas noteikti ir daudz labāk nekā dziļi teoretizēt par to, kas varētu būt labāk... Saģenerējam randomā datus vienā formātā, tos pašus pārdzenam otrā formātā (nu vai citus random), bet lai apjoms būtu vienāds un palaižam ciklā kādu baru ar vaicājumiem. Ar vienu diez vai pietiks, jo starpību diez vai varēs novērtēt. Nu un lai izslēgtu visādas pirmās reizes kešošanas un citus vienreizējus nezināmus faktorus šādus vaicājumus palaižam vairākkārt. Fiksējam laiku, paskatamies rezultātus un izdaram secinājumus. Gints Plivna http://datubazes.wordpress.com
  11. OOOps sorry, iespējams, ka tas nebija domāts tieši man (kaut gan ja jau dauidzskaitlī, tad droši vien arī man) ;), bet es nepaskatījos, ka oriģinālais posts ir no 2005 gada. Vienkārši ieraudzīju, ka posts augšā un atbildēju. Vēlreiz sorry :) Gints Plivna http://datubazes.wordpress.com
  12. Nav gan īsti saprotams, kas bija domāts ar "tā", bet nu ja nu tā kā iepriekšējais lietotājs teica, ka "MySQL prot izmantot tikai vienu indexu vienam selektam/joinam (iespējams, citās DBVS ir savādāk)" tad šeit ir tas kā Oracle to dara: uztaisam tabulu ar 2 number laukiem, pie tam vienā ir unikālas vērtības otrā šajā gadījumā katrai vērtībai atbilst 2 ieraksti: SQL> create table big ( 2 uid1 number not null, 3 uid2 number not null, 4 text varchar2(1000) not null); Table created. SQL> insert into big select rownum, mod(rownum, 100), name 2 from dba_source where rownum <=200; 200 rows created. Uztaisam indexus, izrēķinam statistikas: SQL> create index uid1_idx on big (uid1); Index created. SQL> create index uid2_idx on big (uid2); Index created. SQL> exec dbms_stats.gather_table_stats(user, 'big'); PL/SQL procedure successfully completed. palaižam autotraci un selektu: SQL> set autot traceonly SQL> select * from big 2 where uid1 = 1 3 or uid2 = 2 4 / Execution Plan ---------------------------------------------------------- Plan hash value: 1406454030 --------------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | --------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 3 | 45 | 3 (0)| 00:00:01 | | 1 | TABLE ACCESS BY INDEX ROWID | BIG | 3 | 45 | 3 (0)| 00:00:01 | | 2 | BITMAP CONVERSION TO ROWIDS | | | | | | | 3 | BITMAP OR | | | | | | | 4 | BITMAP CONVERSION FROM ROWIDS| | | | | | |* 5 | INDEX RANGE SCAN | UID2_IDX | | | 1 (0)| 00:00:01 | | 6 | BITMAP CONVERSION FROM ROWIDS| | | | | | |* 7 | INDEX RANGE SCAN | UID1_IDX | | | 1 (0)| 00:00:01 | --------------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 5 - access("UID2"=2) 7 - access("UID1"=1) Nu tātad šeit ir 2 operācijas BITMAP CONVERSION FROM/TO ROWIDS, kur rindiņu norādes (ROWID) tiek konvertētas uz kaut kādu bitu virkni un tad kā es saprotu (precīzu mehānismu nezinu) ātri var iegūt rezultātu, tipa veicot tikai loģisko OR uz šīm bitu virknītēm un tad atkal konvertē atpakaļ uz ROWIDiem, pēc kuriem jau var iegūt konkrētas rindas tabulā. Protams tas ir atkarīgs no datu izvietojuma, ja kāda no vērtōbam ir ļoti bieži sastopama, tad full scans būs lētāks: taisam jaunu tabulu, kas neatšķiras no iepriekšējās, bet atšķiras dati - 2. kolonā būs tikai 2 vērtības 0 un 1 SQL> insert into big1 select rownum, mod(rownum, 2), name 2 from dba_source where rownum <=200; 200 rows created. Un tagad plāns ir pavisam citāds, kā arī sagaidāmo rindiņu skaits ir dauidz lielāks protams: SQL> ed Wrote file afiedt.buf 1 select * from big1 2 where uid1 = 1 3* or uid2 = 0 SQL> SQL> / 101 rows selected. Execution Plan ---------------------------------------------------------- Plan hash value: 3470735819 -------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | -------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 101 | 1515 | 3 (0)| 00:00:01 | |* 1 | TABLE ACCESS FULL| BIG1 | 101 | 1515 | 3 (0)| 00:00:01 | -------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 1 - filter("UID2"=0 OR "UID1"=1) Posts varbūt ne īsti par tēmu, bet iespējams kādam noder ;) Gints Plivna http://datubazes.wordpress.com
  13. Pateikts, ka: 1. MySQL nesupportē check constraintus 2. ar trigeriem arī to nevar normali izdarōt jo nevar raizot kļūdu 3. njā - dots links, kur it kā ir pateikts ka to var izdarōt bet links nestrādā :( 4. dots links uz saitu kur pateikts ka to var izdarōt ar updateable views Nu tā kā kaut kāda info ir, ka to nevar izdarīt veidos X un Y bet var izdarīot veidā Z. Nu kā es sapratu tad neviena no modēm gan CHECK constraintus neenforcē jebkurā gadījumā? Gints Plivna http://datubazes.wordpress.com/
  14. Pēc MySQL manuāļa spriežot MySQLs check constraintus parsē bet neenforcē (kā man patīk šāds formulējums! ;) Bet kaut kas ir šite: http://gilfster.blogspot.com/2005/11/check...n-mysql-50.html Gints Plivna http://datubazes.wordpress.com
  15. Super. Tātad tev ir visas iespējas! Paziņoju, ka saits http://datubazes.wordpress.com/ ir atklāts ;) Šim vakaram ar to saturu, kas tur ir atrodams, man pietiks. Ikviens ir aicināts kaut ko darīt lietas labā, ja ir tāda vēlme un mhmmm tomēr arī drusciņ prasmes ;) Gints
  16. Nu ok beigšu radīt cilvēkos neskaidrību ;) - man personīgi nav nekādu problēmu ar visu šito te, es pilnībā esmu apmierināts ar resursiem angliski, vienkārši man kaut kā pēkšņi ienāca prātā doma, ka latviski par db nekur nekā jēdzīga nav. Nu OK arī auditorija ir maza... Tad nu lūk, man radās aizdomas, ka es varbūt kaut ko esmu palaidis garām un patiesībā kaut kur "viskas" ir. Ja nu galīgi nekā jēdziga nav, tad varbūt ka varētu kaut ko pasākt, lai stāvokli uzlabotu :) Gints
  17. Mhmmm es biju domājis internetā :) Starp citu tur kaut kur būtu jābūt arī manējam par Oracle Designera šādām tādām fīčām :) Gints
  18. Sorry nedaudz par offtopiku, bet: Vai kāds zin citus resursus internetā par datubāzēm latviešu valodā izņemot šo forumu :) un to ko var googlē atrast izmantojot atslēgas vārdus SQL datubāze? Ar domu man personīgi nav nekādu problēmu ar angļu valodu, bet tā gribējās zināt kas ir pieejams latviski, varbūt esmu kaut ko labu palaidis garām... Gints Plivna http://www.gplivna.eu
  19. Njā tikai cik atceros tad 3 versijā piemēram subqueriji MySQLā nebija, bet nu OK, tas jau laikam ir sen noiets etaps :) Gints Plivna http://www.gplivna.eu
  20. Soory par nedaudz offtopiku (bāzes sakarā) bet oraclē tas būtu šādi: Vispirms uztaisam tabulas un iebāžam kaut kādus datus: SQL> create table t1(id number primary key, kaaposti number not null); Table created. SQL> ed Wrote file afiedt.buf 1* create table t2(user_id number not null, kaaposti_h number not null) SQL> / Table created. SQL> ed Wrote file afiedt.buf 1* insert into t1 select rownum, rownum from dba_objects where rownum <=10 SQL> / 10 rows created. SQL> commit; Commit complete. SQL> select * from t1; ID KAAPOSTI ---------- ---------- 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 10 10 10 rows selected. SQL> insert into t2 select mod(rownum, 10) + 1, rownum from dba_objects where rownum <=100; 100 rows created. SQL> select * from t2 where rownum <=12; USER_ID KAAPOSTI_H ---------- ---------- 2 1 3 2 4 3 5 4 6 5 7 6 8 7 9 8 10 9 1 10 2 11 3 12 12 rows selected. Tagad sākam pa klucītim būvēt to ko mums vajag, vispirms sasummējam t2 ierakstus: SQL> select user_id, sum(kaaposti_h) 2 from t2 3 group by user_id; USER_ID SUM(KAAPOSTI_H) ---------- --------------- 1 550 6 500 2 460 4 480 5 490 8 520 3 470 7 510 9 530 10 540 10 rows selected. Vismaz oraclē šādu te datu kopu nekas nekavē izmantot tālāk un joinot ar citu tabulu: SQL> select * from ( 2 select user_id, sum(kaaposti_h) 3 from t2 4 group by user_id) summary, t1 5 where t1.id = summary.user_id; USER_ID SUM(KAAPOSTI_H) ID KAAPOSTI ---------- --------------- ---------- ---------- 3 470 3 3 7 510 7 7 2 460 2 2 8 520 8 8 10 540 10 10 9 530 9 9 4 480 4 4 5 490 5 5 6 500 6 6 1 550 1 1 10 rows selected. Nu un tagad atliek tikai saskaitīt 2 kolonas un tikt vaļā no 2 reiz viena un tā paša ida: SQL> ed Wrote file afiedt.buf 1 select id, kaaposti_h_summa + kaaposti from ( 2 select user_id, sum(kaaposti_h) kaaposti_h_summa 3 from t2 4 group by user_id) summary, t1 5* where t1.id = summary.user_id SQL> / ID KAAPOSTI_H_SUMMA+KAAPOSTI ---------- ------------------------- 3 473 7 517 2 462 8 528 10 550 9 539 4 484 5 495 6 506 1 551 10 rows selected. Tā kā manas zināšanas par MySQL (BTW tas ir MySQL? sākotnējā jautājumā jau nekur tas netika pateikts :) ir visai minorīgas, tad ja nu gadījumā šitais nestrādā, tad jebkurā gadījumā būtu jāstrādā 2 soļos: 1) views uz t2, kas taisa group by 2) joins starp t1 un viewu Gints Plivna http://www.gplivna.eu
  21. OKZ tad pa druskai par visu: par select count(id) un select count(*). Patiesību sakot vispārīgā gadījumā šie 2 vaicājumi var atgriezt pilnīgi dažādus rezultātus, jo count(<KautKas>) skaita visus ierakstu kur <KautKas> IS NOT NULL. Neviens te nav pateicis (ok bet nu droši vien, ka visi to noklusēti domā), ka ID ir NOT NULL :) Tātad skat piemēru: SQL> create table a (id number, data varchar2(4000)); Table created. SQL> insert into a values (null, null); 1 row created. SQL> select count(*) from a; COUNT(*) ---------- 1 1 row selected. SQL> select count(id) from a; COUNT(ID) ---------- 0 1 row selected. SQL> Tagad pieņemot, ka ID ir primārā atslēga (kā tas laikam jau visdrīzāk ir), tad patiesībā ir absolūti vienlaga vai raksta count(id) vai count(*). To var viegli redzēt izmantojot to pašu jau augšminēto autotrace: SQL> drop table a; Table dropped. SQL> create table a (id number not null, data varchar2(4000), 2 constraint a_pk primary key (id)); Table created. SQL> desc a Name Null? Type ----------------------------------------- -------- ---------------------------- ID NOT NULL NUMBER DATA VARCHAR2(4000) SQL> insert into a select rownum, lpad('a', 4000, 'a') from all_objects where rownum <=1000; 1000 rows created. SQL> commit; Commit complete. SQL> exec dbms_stats.gather_table_stats(user, 'a') PL/SQL procedure successfully completed. SQL> set autot on explain SQL> select count(*) from a; COUNT(*) ---------- 1000 1 row selected. Execution Plan ---------------------------------------------------------- Plan hash value: 2685387747 ---------------------------------------------------------------------- | Id | Operation | Name | Rows | Cost (%CPU)| Time | ---------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 2 (0)| 00:00:01 | | 1 | SORT AGGREGATE | | 1 | | | | 2 | INDEX FAST FULL SCAN| A_PK | 1000 | 2 (0)| 00:00:01 | ---------------------------------------------------------------------- SQL> select count(id) from a; COUNT(ID) ---------- 1000 1 row selected. Execution Plan ---------------------------------------------------------- Plan hash value: 2685387747 ---------------------------------------------------------------------- | Id | Operation | Name | Rows | Cost (%CPU)| Time | ---------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 2 (0)| 00:00:01 | | 1 | SORT AGGREGATE | | 1 | | | | 2 | INDEX FAST FULL SCAN| A_PK | 1000 | 2 (0)| 00:00:01 | ---------------------------------------------------------------------- SQL> OK tātad ko tur darīja un varēja redzēt? Vispirms nodropoja, tad uztaisīja tabulu ar 2 laukiem, vienu primārās atslēgas lauku, otru vienkārši datu kluci, lai būtu kaut kāds balasts :) Tālāk ielika 1K rindiņas un ar dbms_stats izrēķināja statistikas tabulai un defaultā kaskādē arī visiem indeksiem, šai gadījumā PK indeksam. set autot on explain nozīmē enablēt autotraci un explain ir rādīt izpildes plānu Nu un kā mēs redzam tad abos gadījumos tas ir pilnīgi vienāds, tb INDEX FAST FULL SCAN pa primārās atslēgas indexu. Ja tabulai nav primārās atslēgas indexa, tad būtu nepieciešams FULL SCAN, jo tikai tādā veidā count(*) var iegūt visu rezultātu. NU ok vēl derētu arī NOT NULL kolona ar indexu, tb Oracle ir pietiekami gudra, lai transformētu un optimizētu vaicājumu tādā veidā, lai ar iespējami mazākiem resursiem izpildītu to, ko viņai prasa. Tātad būtu nepieciešams noskaidrot kāds tiešām ir izpildes plāns un tad rīkoties tālāk. BET IR VIENA PAVISAM CITA LIETA! No veselā saprāta viedokļa ir ļoti apšaubāma šāda vajadzība kā tāda - bieži (kā vismaz izskatās no oriģināla jautājuma) izpildīt šādu vaicājumu uz 90M tabulu. Šī prasība kā tāda ir neprātīga - vai tiešām kādam ir svarīgi bieži zināt vai tabulā ir 90 123 123 vai 90 321 321 ieraksti??? Iesaku stingri padomāt par šādas prasības nepieciešamību. OK tagad par Oracle licencēšanu un ātrdarbību Visām Oracle versijam (nu labi neesmu 100% drošs par personal edition) bet ieskaitot Enterprise Edition, Standard edition un arī Express Edition ir viena un tā pati core. Un tās kustība ir atkarīga tikai no tā vai dzelzim ir pietiekami resursi, vai dzelzis ir noslogots ar citām paralēlām (parasti I/O) darbībām un to cik efktīvi ir uzrakstīts kods. Principā uz vienas un tās pašas kastes gan EE, gan SE, gan XE būtu jādarbojas apmēram vienādi pie tās pašas nsolodzes un tām pašām darbībām. Tā kā runāt par (ne)licencēšanu vismaz no ātrdarbības viedokļa nav īsti vietā. Protams ir jānem vērā tas, ka XE piemēram ir ierobežojums uz RĀMI 1 G un dabīgi, ka uz tās pašas kastes, ja RĀMis ir liels tad EE ar tam pieejamu 4G visticamāk griezīsies ātrāk. Te var redzēt edīciju salīdzinājumu pa fīčām un citiem ierobežojumiem: http://www.oracle.com/database/product_editions.html Gints Plivna http://www.gplivna.eu
×
×
  • Create New...