Question

I have written a procedure which takes several input parameters. I need to validate the input. If they are valid values they have to be present in the database table - attribute_values. The problem is attribute_values table contains million records. I am now supposed to improve the performance of select query. For validating 1 input parameter I am doing something like this.

SELECT COUNT(1) INTO COUNT_VAR 
  FROM ATTRIBUTE_VALUES A 
 WHERE A.ATTRIBUTE_VALUE = input_paramater1;
IF COUNT_VAR = 1 THEN 
SELECT ATTRIBUTE_VALUE_ID INTO MYVAR1 
  FROM ATTRIBUTE_VALUES A 
 WHERE A.ATTRIBUTE_VALUE =  input_paramater1; 
END IF; 

other_procedure(MYVAR1);

Any suggestions for improving performance of selecting from a table which contains a million records. Also out of count(*) and count(1) which is better.

Was it helpful?

Solution

Rather than doing a SELECT COUNT(*)... followed by a SELECT ID..., both against the same table, I suggest you rework this logic as follows:

BEGIN
  SELECT ATTRIBUTE_VALUE_ID
    INTO MYVAR1 
    FROM ATTRIBUTE_VALUES A 
    WHERE A.ATTRIBUTE_VALUE = INPUT_PARAMETER1 AND
          ROWNUM = 1;

  COUNT_VAR := 1;
EXCEPTION
  WHEN NO_DATA_FOUND THEN
    COUNT_VAR := 0;
    MYVAR1 := NULL;
END;

OTHER_PROCEDURE(MYVAR1);

This helps two ways. First, in my experience SELECT COUNT... is slow, so I try to avoid it whenever possible. Second, this not only saves a second query but lets you take advantage of the standard exception handling built in to PL/SQL.

Share and enjoy.

EDIT: given OP's revelation (in comments to the question, above) that ATTRIBUTE_VALUES.ATTRIBUTE_VALUE is not unique I've updated the code above so that it will not fail if more than one row would be returned.

OTHER TIPS

For these queries, I would suggest an index:

create index attribute_values_attribute_value on attribute_values(attribute_value);

This should suffice for your purposes.

3 STEPS:

1) If possible partition the table.

2) Create Index as follows

CREATE INDEX idx1_attribute_values ON attribute_values(attribute_value, attribute_value_id);

3) Use the following coding style for better results

BEGIN
    SELECT attribute_value_id
      INTO myvar1
      FROM attribute_values a
     WHERE a.attribute_value = input_parameter1;
EXCEPTION
WHEN others THEN
    myvar1 := 0;    -- Handle the error codes accordingly
END;

If it still doesn't work, post the plan of the query.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top