Jump to content
php.lv forumi

lielas DB vaicājuma ilgums


cilveks

Recommended Posts

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

×
×
  • Create New...