Many database performance problems can be resolved via a top-down approach: you look at database performance globally (using statspack or AWR report) and then you work your way down to specific SQL consuming most of resources. This approach breaks when the application is not using bind variables. The reason for that is that performance reports depend on sql_id to identify a statement, and in absence of cursor sharing a single SQL statement has as many sql_id’s as there are combinations of literal parameters. So if your heaviest query is something like
SELECT * FROM T1 WHERE X=:B1,
then you’ll see in in AWR top-SQL lists, but if it’s
SELECT * FROM T1 WHERE X="some literal value",
then at best you’ll see a bunch of similar statements in the lists, each responsible for a small fraction of the workload. There is also a good chance that your heaviest SQL won’t show up in those lists at all, if it’s overshadowed by frequently run statements with unchanging parameters (or using binds).
Continue reading “Where AWR can’t help: identifying top-SQL in absence of cursor sharing”