Hello Tom,
First of all, thank for your time and help.
I have a procedure that receives more or less 26 parameters (most of them optional) and this dynamic query.
This query takes 1 min 36 with 99999 rows. Do you think a better way to do it using only sql statement not a dynamic one? I tried it but I found a problem with the order by clause because the parameter p_order_by could be 'col1 ASC, col2 DESC, ...'
v_select_stmt := 'SELECT * FROM ( ';
v_select_stmt := v_select_stmt || 'SELECT rownum as rnum, y.* FROM( ';
v_select_stmt := v_select_stmt || 'SELECT /*+ FIRST_ROWS(' || TO_NUMBER(p_maximumrows) || ') */ COUNT(1) OVER() as totalRows, ';
v_select_stmt := v_select_stmt || 'x.col1, x.col2, x.col2, x.col4, x.col5, x.col6, x.col7, x.col8, x.col9, x.col10 ';
v_select_stmt := v_select_stmt || 'FROM vView ';
v_select_stmt := v_select_stmt || 'WHERE id = ' || p_lcs_event_id || ' ';
v_select_stmt := v_select_stmt || 'AND (' || p_backup || ' = 1 OR x.event_id = 2) ';
IF p_iresolved = 0 THEN
v_select_stmt := v_select_stmt || 'AND (x.time_close IS NULL) ';
END IF;
IF p_region_id != 0 THEN
v_select_stmt := v_select_stmt || ' AND x.rid =' || p_rid || ' ';
END IF;
IF p_region_name IS NOT NULL THEN
v_select_stmt := v_select_stmt || ' AND LOWER(x.rname) LIKE ''%' || LOWER (p_rname) || '%' || '''';
END IF;
IF p_acctype IS NOT NULL THEN
v_select_stmt := v_select_stmt || ' AND LOWER(x.acctype) LIKE ''%' || LOWER p_acctype || '%' || '''';
END IF;
IF p_mname IS NOT NULL THEN
v_select_stmt := v_select_stmt || ' AND LOWER(x.mname) LIKE ''%' || LOWER p_mname || '%' || '''';
END IF;
IF p_county IS NOT NULL THEN
v_select_stmt := v_select_stmt || ' AND LOWER(x.county) LIKE ''%' || LOWER (p_county) || '%' || '''';
END IF;
IF p_aname IS NOT NULL THEN
v_select_stmt := v_select_stmt || ' AND LOWER(x.aname) LIKE ''%' || LOWER (p_aname)|| '%' || '''';
END IF;
IF p_cname IS NOT NULL THEN
v_select_stmt := v_select_stmt || ' AND LOWER(x.cname) LIKE ''%' || LOWER (p_cname) || '%' || '''';
END IF;
IF p_accnumber IS NOT NULL AND p_accoperator IS NOT NULL
THEN
IF p_accoperator = 'Contains' THEN
v_select_stmt := v_select_stmt || ' AND LOWER(x.accnumber) LIKE ''%' || LOWER (p_accnumber) || '%' || '''';
END IF;
IF p_accoperator = 'DoesNotContain' THEN
v_select_stmt := v_select_stmt || ' AND LOWER(x.accnumber) NOT LIKE ''%' || LOWER (p_accnumber) || '%' || '''';
END IF;
IF p_accoperator = 'StartsWith' THEN
v_select_stmt := v_select_stmt || ' AND LOWER(x.accnumber) LIKE ' || '''' || LOWER (p_accnumber) || '%' || '''';
END IF;
IF p_accoperator = 'EndsWith' THEN
v_select_stmt := v_select_stmt || ' AND LOWER(x.accnumber) LIKE ''%' || LOWER (p_accnumber) || '''';
END IF;
IF p_accoperator = 'EqualTo' THEN
v_select_stmt := v_select_stmt || ' AND LOWER(x.accnumber) = ' || '''' || LOWER (p_accnumber) || '''';
END IF;
END IF;
IF p_accname IS NOT NULL AND p_accnoperator IS NOT NULL THEN
IF p_accnoperator = 'Contains' THEN
v_select_stmt := v_select_stmt || ' AND LOWER(x.accname) LIKE ''%' || LOWER (p_accname ) || '%' || '''';
END IF;
IF p_accnoperator = 'DoesNotContain' THEN
v_select_stmt := v_select_stmt || ' AND LOWER(x.accname) NOT LIKE ''%' || LOWER (p_accname )|| '%' || '''';
END IF;
IF p_accnoperator = 'StartsWith' THEN
v_select_stmt := v_select_stmt || ' AND LOWER(x.accname) LIKE ' || '''' || LOWER (p_accname ) || '%' || '''';
END IF;
IF p_accnoperator = 'EndsWith' THEN
v_select_stmt := v_select_stmt || ' AND LOWER(x.accname) LIKE ''%' || LOWER (p_accname ) || '''';
END IF;
IF p_accnoperator = 'EqualTo' THEN
v_select_stmt := v_select_stmt || ' AND LOWER(x.accname) = ' || '''' || LOWER (p_accname ) || '''';
END IF;
END IF;
IF p_order_by IS NULL THEN
IF p_region_id != 0 THEN
v_select_stmt := v_select_stmt || ' ORDER BY col2 ASC, col3 ASC, col4 ASC, col1 ASC NULLS FIRST ';
ELSE
v_select_stmt := v_select_stmt || ' ORDER BY col1 ASC, col3 ASC, col4 ASC NULLS FIRST ';
END IF;
ELSE
v_select_stmt := v_select_stmt || ' ORDER BY ' || p_order_by || ' NULLS FIRST '; -- could be any column ASC/DESC separated with ,
END IF;
v_select_stmt := v_select_stmt || ') y ) ';
v_select_stmt := v_select_stmt || ' WHERE rnum between ' || TO_NUMBER(p_startrowindex) || ' and ' || TO_NUMBER(p_startrowindex + p_maximumrows) || '';
Thanks in advance
Regards,
Diana
The big thing here that is doing to hurt you is the "totalrows", because I can you're looking to use a pagination style query here.
We can do all sorts of good optimizations for those style of queries........but only if you don't go asking for the the total row count.
Here's some background on that
The other thing is that I can see a lot of your predicate are wild card based. It might be worth looking at perhaps using a Text based index here and doing a keyword search.
Plenty of examples of that here on AskTOM - just search for "CTXSYS"