Reputation: 315
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.
Upvotes: 0
Views: 128
Reputation: 50017
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.
Upvotes: 2
Reputation: 151
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.
Upvotes: 0
Reputation: 1269543
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.
Upvotes: 1