The LIKE Bindvariable Dilemma
Posted by carl.reitschuster on 20th February 2007
hi,
everybody tells you to use bind variables (reduced parses) and that’s ok. But in some circumstances you get a lot of problems with it. Using bind variables with the LIKE operator could cause horrible performance even you index that column and you do not use a ‘%’ at the start of the searched string.
Case 1 comparing with = operator :
WHERE Company.Customer = :P02
TABLE ACCESS BY LOCAL INDEX ROWID Depth=18 Object owner=ISIS Object name=COMPANY Cost=4 CPU cost=28254 IO cost=4 Cardinality=1 Bytes=289 Options=BY LOCAL INDEX ROWID Operation=TABLE ACCESS Optimizer=ANALYZED Partition id=18 Partition start=2 Partition stop=2
INDEX RANGE SCAN Depth=19 Object owner=ISIS Object name=COMPANY_IX01 Cost=3 CPU cost=21764 IO cost=3 Cardinality=1 Access predicates="COMPANY"."CUSTOMER"=:P02 Options=RANGE SCAN Operation=INDEX Optimizer=ANALYZED Partition id=19 Partition start=2 Partition stop=2
Yeah!! the optimizer chooses the index - very fast response - in this case.
Case 2 comparing with LIKE operator :
WHERE Company.Customer LIKE :P02
TABLE ACCESS FULL Depth=18 Object owner=ISIS Object name=COMPANY Cost=45241 CPU cost=8354827075 IO cost=44959 Cardinality=346919 Bytes=100259591 Filter predicates="COMPANY"."CUSTOMER" LIKE :P02 Options=FULL Operation=TABLE ACCESS Optimizer=ANALYZED Partition id=27 Partition start=2 Partition stop=2
Oh my god!!! what is Oracle doing here???? Full Tablescan over 6.6m rows. The reason for is that dummy 5% assumption. Oracle assumes to scan 5% rows (look at the expected cardinality it’s about 5% of 6.8m) of the table using LIKE with bind var. Unfortunately this is the limit for a full table scan.
We fixed that with a higher affinity to index blocks. Also there is an internal parameter known to cahnge globally the way oracle calculate the expected cardinality of the LIKE operator. But a better way in the future release of the software will be: If the queried field is full qualified (means full length without ‘%’ or ‘_’) then the comparison operator is used instead of like.
cheers
Karl
Posted in Tuning, 9.2, 10.2, Statistics, Execution Plan, advanced, 10.1 | No Comments »