Let's assume there are two database users: (1) A user named APP who connects to the database very often and queries and modifies many tables in his own schema. (2) A user named WEB who only connects to the database rarely and only queries and modifies a few tables in the APP schema.
I need to limit the table access of both users depending on the data. I'm using the Oracle Virtual Private Database (VPD) feature (sometimes also known as fine-grained access control) to do this. For this question only the rule which limits the APP user is important. The rule which limits the WEB user needs to be in a seperate VPD policy (I might later ask a similar question for that policy).
Which of the following two implementations would give the better query and DML performance for the APP user?
1) Create the policy with policy_type dbms_rls.SHARED_CONTEXT_SENSITIVE
and implement the policy function like this:
FUNCTION get_predicate(i_schema IN VARCHAR2, i_object IN VARCHAR2)
RETURN VARCHAR2
AS
BEGIN
IF SYS_CONTEXT('USERENV', 'SESSION_USER') = 'WEB' THEN
RETURN NULL;
END IF;
RETURN 'some_id_column = SYS_CONTEXT(''APP'', ''some_id'')';
END get_predicate;
2) Create the policy with policy_type dbms_rls.SHARED_STATIC
and implement the policy function like this:
FUNCTION get_predicate(i_schema IN VARCHAR2, i_object IN VARCHAR2)
RETURN VARCHAR2
AS
BEGIN
RETURN 'SYS_CONTEXT(''USERENV'', ''SESSION_USER'') = ''WEB'' OR some_id_column = SYS_CONTEXT(''APP'', ''some_id'')';
END get_predicate;
Note that the APP user uses client connection pooling (provided by ODP.NET), so it should only open a few connections for each application usage session. There are around 100 clients which will connect to the database.