Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
SELECT COUNT(ID) FROM some_table WHERE some_condition
...
if(result > 0) then ...
SQL> set autotrace on
SQL> select count(*) from test;
COUNT(*)
----------
1
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=ALL_ROWS (Cost=586 Card=1)
1 0 SORT (AGGREGATE)
2 1 INDEX (FAST FULL SCAN) OF 'SYS_C0051757' (INDEX (UNIQUE)
) (Cost=586 Card=1)
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
2102 consistent gets
0 physical reads
0 redo size
350 bytes sent via SQL*Net to client
431 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
SQL> select 'hello' from test where rownum = 1;
'HELL
-----
hello
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=ALL_ROWS (Cost=586 Card=1)
1 0 COUNT (STOPKEY)
2 1 INDEX (FAST FULL SCAN) OF 'SYS_C0051757' (INDEX (UNIQUE)
) (Cost=586 Card=1)
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
2101 consistent gets
0 physical reads
0 redo size
352 bytes sent via SQL*Net to client
431 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
SQL> select 'hello' from test where id> 0 and rownum = 1;
'HELL
-----
hello
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=ALL_ROWS (Cost=2 Card=1 Bytes=13)
1 0 COUNT (STOPKEY)
2 1 INDEX (RANGE SCAN) OF 'SYS_C0051757' (INDEX (UNIQUE)) (C
ost=2 Card=1 Bytes=13)
Statistics
----------------------------------------------------------
58 recursive calls
0 db block gets
6456 consistent gets
0 physical reads
0 redo size
352 bytes sent via SQL*Net to client
431 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
5 sorts (memory)
0 sorts (disk)
1 rows processed
Можно даже не делать ограничение выборки (LIMIT, TOP, FIRST etc.) Просто становимся на первую полученную запись. Любая нормальная СУБД не будет фетчить всё подряд пока не попросишь.
Чувствуете разницу? Надеюсь понятно объяснил.
Connected to Oracle Database 11g Enterprise Edition Release 11.2.0.2.0
Connected as ZTXN@ORCL01
SQL> set timing on
SQL> select count(*) from test;
COUNT(*)
----------
0
Executed in 14.437 seconds
SQL> select 'hello' from test where rownum = 1;
'HELLO'
-------
Executed in 15.812 seconds
create table test as select
lpad('1',100,'1') val1
,lpad('2',100,'2') val2
,lpad('3',100,'3') val3
,lpad('4',100,'4') val4
,lpad('5',100,'5') val5
,lpad('6',100,'6') val6
,lpad('7',100,'7') val7
,lpad('8',100,'8') val8
from dual connect by level < 1e6;
delete from test;
commit;
SQL> select id from test where rownum = 1;
ID
----------
1000000
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=ALL_ROWS (Cost=586 Card=1 Bytes=1
3)
1 0 COUNT (STOPKEY)
2 1 INDEX (FAST FULL SCAN) OF 'SYS_C0051757' (INDEX (UNIQUE)
) (Cost=586 Card=1 Bytes=13)
Statistics
----------------------------------------------------------
7 recursive calls
0 db block gets
2261 consistent gets
0 physical reads
0 redo size
344 bytes sent via SQL*Net to client
431 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
where rownum = 1. Мне интересен был вариант именно без него.Листья индекса для удаленных данных так же физически не освобождаются, как и данные таблицы
Сейчас мусор подчищается при первом же SELECTе к данным почищенной таблицы
Погодите, в этом примере вы оставили where rownum = 1. Мне интересен был вариант именно без него.
SQL> select id from test;
ID
----------
1000000
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=ALL_ROWS (Cost=586 Card=1 Bytes=1
3)
1 0 INDEX (FAST FULL SCAN) OF 'SYS_C0051758' (INDEX (UNIQUE))
(Cost=586 Card=1 Bytes=13)
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
2102 consistent gets
0 physical reads
0 redo size
344 bytes sent via SQL*Net to client
431 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
SQL> select * from (
2 select /*+first_rows*/ id from test order by id desc
3 )
4 where rownum = 1;
ID
----------
1000000
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=HINT: FIRST_ROWS (Cost=2146 Card=
1 Bytes=13)
1 0 COUNT (STOPKEY)
2 1 VIEW (Cost=2146 Card=1 Bytes=13)
3 2 INDEX (FULL SCAN DESCENDING) OF 'SYS_C0051758' (INDEX
(UNIQUE)) (Cost=2146 Card=1 Bytes=13)
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
3 consistent gets
0 physical reads
0 redo size
344 bytes sent via SQL*Net to client
431 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
Select count(id) from mo_chng where tablename='SPRT'
PLAN (MO_CHNG NATURAL)
------ Performance info ------
Prepare time = 0ms
####Execute time = 109ms
Avg fetch time = 109,00 ms
####Fetches from cache = 280 646
select first 1 1 from mo_chng where tablename='SPRT'
Plan
PLAN (MO_CHNG NATURAL)
------ Performance info ------
Prepare time = 0ms
#####Execute time = 15ms
Avg fetch time = 15,00 ms
####Fetches from cache = 1 301
SELECT * FROM some_table limit 1
if(проверяем есть ли запись)
Как узнать, стоит ли оптимизировать MySQL запросы?