26
Глава 1.
Оценка
большой таблицы от начала до конца . Решение очевидно: создать допол-
нительный индекс по столбцу accountid и запустить процесс снова . Ка-
ков же результат? Теперь программа работает немного меньше четырех
минут, значит, производительность возросла в 3,1 раза .
Для нашего администратора MySQL, это, скорее всего, конец истории .
Однако для его коллег, работающих с Oracle и SQL Server, все не так
просто . Не менее опытный, чем администратор MySQL, администратор
Oracle активизировал бы магическое оружие настройки Oracle, извест-
ное среди посвященных как
event 10046 level 8 (или использовал бы с тем
же эффектом «advisor»), и получил бы файл трассировки, ясно показы-
вающий, как тратилось время . Из такого файла трассировки вы може-
те определить, сколько раз выполнялись операторы, сколько процес-
сорного времени они использовали, фактическую продолжительность
работы и другую важную информацию, например количество логиче-
ских считываний (которые показаны в файле трассировки как запрос
и текущая запись), то есть количество блоков данных, к которым был
осуществлен доступ для обработки запроса, и периоды ожидания, кото-
рые объясняют, по крайней мере частично, разницу между затраченным
процессорным временем и фактическим временем работы программы:
****************************************************************************
SQL ID : 1nup7kcbvt072
select txid,amount,curr
from
transactions where accountid=:1 and txdate >= to_date(:2, 'DD-MON-YYYY') -
30 order by txdate
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- --------
Parse 1 0.00 0.00 0 0 0 0
Execute 252 0.00 0.01 0 0 0 0
Fetch 11903 32.21 32.16 0 2163420 0 117676
------- ------ -------- ---------- ---------- ---------- --------
total 12156 32.22 32.18 0 2163420 0 117676
Misses in library cache during parse: 1
Misses in library cache during execute: 1
Optimizer mode: ALL_ROWS
Parsing user id: 88
Rows
Row Source Operation
------- ---------------------------------------------------
495 SORT ORDER BY (cr=8585 [...] card=466)
495 TABLE ACCESS FULL TRANSACTIONS (cr=8585 [...] card=466)
Elapsed times include waiting on following events:
Event waited on Times Max. Wait Total Waited
---------------------------------- Waited ---------- ------------
SQL*Net message to client 11903 0.00 0.02
Простой
пример
27
SQL*Net message from client 11903 0.00 2.30
********************************************************
SQL ID : gx2cn564cdsds
select threshold
from
thresholds where iso=:1
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ----------
Parse 117674 2.68 2.63 0 0 0 0
Execute 117674 5.13 5.10 0 0 0 0
Fetch 117674 4.00 3.87 0 232504 0 114830
------- ------ -------- ---------- ---------- ---------- ----------
total 353022 11.82 11.61 0 232504 0 114830
Misses in library cache during parse: 1
Misses in library cache during execute: 1
Optimizer mode: ALL_ROWS
Parsing user id: 88
Rows Row Source Operation
------- ---------------------------------------------------
1 TABLE ACCESS BY INDEX ROWID THRESHOLDS (cr=2 [...] card=1)
1 INDEX UNIQUE SCAN SYS_C009785 (cr=1 [...] card=1)(object id 71355)
Elapsed times include waiting on following events:
Event waited on Times Max.
Wait Total Waited
--------------------------------- Waited ---------- --------------
SQL*Net message to client 117675 0.00 0.30
SQL*Net message from client 117675 0.14 25.04
***********************************************************************
Видя TABLE ACCESS FULL TRANSACTION в плане выполнения самого медлен-
ного запроса (особенно, когда он исполнен 252 раза), администратор
Oracle отреагирует так же, как и администратор MySQL . В Oracle тот
же самый индекс по столбцу accountid увеличил производительность
в 1,2 раза, уменьшив время выполнения приблизительно до минуты
и 20 секунд .
Администратор SQL Server может использовать SQL Profiler или запу-
стить следующий скрипт:
select a.*
from (select execution_count,
total_elapsed_time,
total_logical_reads,
substring(st.text, (qs.statement_start_offset/2) + 1,
((case statement_end_offset