Gints Plivna Posted September 27, 2007 Report Share Posted September 27, 2007 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 Link to comment Share on other sites More sharing options...
Recommended Posts