sql tuning | calculating logical reads made by a query
one day a dba reported high resource usage by a query, but it was 'well-optimized' and the runtime was as expected, then what was wrong? logical read was high.
to calculate logical reads made by a query:
DECLARE
READS NUMBER;
OUTPUT NUMBER;
L_SQL VARCHAR2(4000);
L_MULTIPLIER NUMBER;
BEGIN
L_SQL := q'[SELECT *
FROM ALL_TABLES T, (SELECT 1
FROM DUAL
CONNECT BY LEVEL<=:P_MULTIPLIER)]';
L_MULTIPLIER := 10000;
EXECUTE IMMEDIATE 'ALTER SYSTEM FLUSH BUFFER_CACHE';
EXECUTE IMMEDIATE 'ALTER SYSTEM FLUSH SHARED_POOL';
SELECT NVL(ST.VALUE, 0) INTO READS
FROM V$STATNAME S, V$MYSTAT ST
WHERE ST.STATISTIC# = S.STATISTIC#
AND S.NAME = 'session logical reads';
EXECUTE IMMEDIATE L_SQL USING L_MULTIPLIER;
SELECT NVL((ST.VALUE - READS), 0) INTO OUTPUT
FROM V$STATNAME S, V$MYSTAT ST
WHERE ST.STATISTIC# = S.STATISTIC#
AND S.NAME = 'session logical reads';
DBMS_OUTPUT.PUT_LINE('Logical reads before: '||READS);
DBMS_OUTPUT.PUT_LINE('Logical reads after: '||(OUTPUT+READS));
DBMS_OUTPUT.PUT_LINE('Number of logical reads made by the query: '||OUTPUT);
END;
for this example query, I got the same number of logical reads made when the L_MULTIPLIER
was changed, as expected.
L_MULTIPLIER := 100;
Logical reads before: 294064
Logical reads after: 296383
Number of logical reads made by the query: 2319
L_MULTIPLIER := 10000;
Logical reads before: 300532
Logical reads after: 302851
Number of logical reads made by the query: 2319
maybe you can ask your DBAs to check the cache hit ratio and do their magic there.