9 RDFビュー: RDFとしてのリレーショナル・データ

Oracle Spatial and Graph RDFセマンティク・グラフのリレーショナル・データ上にRDFビューを作成し、使用することができます。

リレーショナル・データは、W3Cドキュメントに説明のあるRDB2RDFマッピングの2つのフォームのうちの1つを使用して、直接マッピングとR2RMLマッピングで仮想RDFトリプルとして表示されます。

9.1 リレーショナル・データに対してRDFビューを使用する理由

リレーショナル・データでRDFビューを使用すると、異なるソースから入手可能なデータを統合することができます。

リレーショナル・データと一致するRDFトリプルを物理的に格納しなくても、リレーショナル・データの長所を利用することができます。Oracle Database 12cリリース1 (12.1)でRDFビューがRDFセマンティク・グラフに含められる前は、カスタムSQL問合せを書き込むか、非標準のマッピングを使用して、生成されたRDFトリプルを物理的にRDFモデルに格納する必要がありました。

RDFデータにリレーショナル・データのマッピングを作成する最も単純な方法は、SEM_APIS.CREATE_RDFVIEW_MODELプロシージャをコールしてRDFビューを作成することと、RDFとして表示したい内容の表またはビューのリストを指定することです。これが、それらのリレーショナル表またはビューの直接マッピングになります。

よりカスタマイズされたマッピングを行うには、R2RMLマッピング・ドキュメントを(たとえばTurtleを使用したRDFで)記述し、必要なマッピングを指定して、マッピング・ドキュメントを(N-Triple形式に変換した後で)ステージング表にロードし(表の定義は、「ステージング表を使用したセマンティク・データのバルク・ロード」を参照)、さらにSEM_APIS.CREATE_RDFVIEW_MODELプロシージャをコールして、ステージング表の名前を指定することでRDFビューを作成する方法があります。

また、ステージング表ベースの方法のかわりに、r2rml_stringパラメータを指定して、R2RMLマッピングを(TurtleまたはN-Triple構文を使用して) SEM_APIS.CREATE_RDFVIEW_MODELに直接指定できます。

9.2 RDFビューのAPIサポート

SEM_APISパッケージには、RDFビューの作成、削除およびエクスポート(つまりRDFビューの実体化)を行うサブプログラムが含まれています。

RDFビューはRDFモデルとして作成されますが、物理的にはメタデータのみが含まれています。実際のデータは、RDFビューが作成されたリレーショナル表に引き続き格納されます。(SEM_APISサブプログラムの詳細は、「SEM_APISパッケージ・サブプログラム」を参照してください。)

この項の残りの例では、起動元のスキーマに次のリレーショナル表が存在することを前提としています。

CREATE TABLE dept (
  deptno NUMBER CONSTRAINT pk_DeptTab_deptno PRIMARY KEY,
  dname VARCHAR2(30),
  loc VARCHAR2(30)
);
 
CREATE TABLE emp ( 
  empno NUMBER PRIMARY KEY,
  ename VARCHAR2(30),
  job VARCHAR2(20),
  deptno NUMBER REFERENCES dept (deptno)
);

これらの表が起動元とは異なるスキーマ(たとえば、SCOTT)にある場合、これらの表の名前を指定する際に、スキーマ修飾された表名("SCOTT"."DEPT"および"SCOTT"."EMP")を使用する必要があることに注意してください。

9.2.1 直接マッピングを使用したRDFビューの作成

例9-1では、EMPとDEPTという2つの表の直接マッピングに、ベース接頭辞http://empdb/を使用してRDFビュー・モデルを作成しています。(仮想)RDF語句は、A Direct Mapping of Relational Data to RDF、W3C勧告(http://www.w3.org/TR/rdb-direct-mapping/)に従って作成されます。

例9-1 直接マッピングを使用したRDFビューの作成

BEGIN
  sem_apis.create_rdfview_model(
    model_name => 'empdb_model',
    tables => SYS.ODCIVarchar2List('EMP', 'DEPT'),
    prefix => 'http://empdb/',
    options => 'KEY_BASED_REF_PROPERTY=T'
  );
END;
/

生成されるプロパティを表示するには、次の文を入力します(オブジェクトは、TESTUSERというユーザーのスキーマに作成されるとします)。

SELECT DISTINCT p
  FROM TABLE(SEM_MATCH(
    '{?s ?p ?o}',
    SEM_Models('empdb_model'),
    NULL,
    NULL,
    NULL));
 
P                                                                               
--------------------------------------------------------------------------------
http://empdb/TESTUSER.EMP#DEPTNO                                                
http://empdb/TESTUSER.DEPT#LOC                                                  
http://empdb/TESTUSER.EMP#JOB                                                   
http://empdb/TESTUSER.DEPT#DEPTNO                                               
http://empdb/TESTUSER.EMP#ENAME                                                 
http://www.w3.org/1999/02/22-rdf-syntax-ns#type                                 
http://empdb/TESTUSER.DEPT#DNAME                                                
http://empdb/TESTUSER.EMP#EMPNO                                                 
http://empdb/TESTUSER.EMP#ref-DEPTNO                                            
 
9 rows selected.

例9-2 CONFORMANCE=Tの使用

例9-2は本質的に例9-1と同じですが、CONFORMANCE=Tオプションを使用します(SEM_APIS.CREATE_RDFVIEW_MODELoptionsパラメータの説明を参照)。出力について、スキーマ名はプロパティ・リストに含まれないことに注意してください。たとえば、例9-2の最初の出力レコードがhttp://empdb/DEPT#LOCであるのに対し、例9-1で生成されるもう一方はhttp://empdb/TESTUSER.DEPT#LOCとなります。

BEGIN
  sem_apis.create_rdfview_model(
    model_name => 'empdb_model',
    tables => SYS.ODCIVarchar2List('EMP', 'DEPT'),
    prefix => 'http://empdb/',
    options => 'CONFORMANCE=T'
  );
END;
/

SELECT DISTINCT p
  FROM TABLE(SEM_MATCH(
    '{?s ?p ?o}',
    SEM_Models('empdb_model'),
    NULL,
    NULL,
    NULL));
 
P                                                                               
--------------------------------------------------------------------------------
http://empdb/DEPT#LOC                                                           
http://empdb/EMP#ref-DEPTNO                                                     
http://empdb/EMP#ENAME                                                          
http://empdb/DEPT#DEPTNO                                                        
http://empdb/EMP#JOB                                                            
http://empdb/EMP#EMPNO                                                          
http://www.w3.org/1999/02/22-rdf-syntax-ns#type                                 
http://empdb/DEPT#DNAME                                                         
http://empdb/EMP#DEPTNO                                                         
 
9 rows selected.

9.2.2 R2RMLマッピングを使用したRDFビューの作成

2つの表EMPとDEPTを使用してRDFビューを、独自のカスタマイズによって作成する場合、Turtleを使用して指定したR2RMLマッピング・ドキュメントを作成することができます。次に例を示します。

@prefix rr: <http://www.w3.org/ns/r2rml#>.
@prefix xsd: <http://www.w3.org/2001/XMLSchema#>.
@prefix ex: <http://example.com/ns#>.
 
ex:TriplesMap_Dept
    rr:logicalTable [ rr:tableName "DEPT" ];
    rr:subjectMap [
        rr:template "http://data.example.com/department/{DEPTNO}";
        rr:class ex:Department;
    ];
    rr:predicateObjectMap [
        rr:predicate ex:deptNum;
        rr:objectMap [ rr:column "DEPTNO" ; rr:datatype xsd:integer ];
    ];
    rr:predicateObjectMap [
        rr:predicate ex:deptName;
        rr:objectMap [ rr:column "DNAME" ];
    ];
    rr:predicateObjectMap [
        rr:predicate ex:deptLocation;
        rr:objectMap [ rr:column "LOC" ];
    ].
 
ex:TriplesMap_Emp
    rr:logicalTable [ rr:tableName "EMP" ];
    rr:subjectMap [
        rr:template "http://data.example.com/employee/{EMPNO}";
        rr:class ex:Employee;
    ];
    rr:predicateObjectMap [
        rr:predicate ex:empNum;
        rr:objectMap [ rr:column "EMPNO" ; rr:datatype xsd:integer ];
    ];
    rr:predicateObjectMap [
        rr:predicate ex:empName;
        rr:objectMap [ rr:column "ENAME" ];
    ];
    rr:predicateObjectMap [
        rr:predicate ex:jobType;
        rr:objectMap [ rr:column "JOB" ];
    ];
    rr:predicateObjectMap [
        rr:predicate ex:worksForDeptNum;
        rr:objectMap [ rr:column "DEPTNO" ; rr:dataType xsd:integer ];
    ];
    rr:predicateObjectMap [
        rr:predicate ex:worksForDept;
        rr:objectMap [ 
          rr:parentTriplesMap ex:TriplesMap_Dept ; 
          rr:joinCondition [ rr:child "DEPTNO"; rr:parent "DEPTNO" ]]].

その後、(N-Triples形式に変換された)R2RMLマッピングを、SCOTT.R2RTABなどのステージング表にロードし、この表へのSELECT権限をMDSYSに付与します。

次に、例9-3の場合のように、SEM_APIS.CREATE_RDFVIEW_MODELをコールします。

例9-3 ステージング表に格納されているR2RMLマッピングによるRDFビューの作成

BEGIN
  sem_apis.create_rdfview_model(
    model_name => 'empdb_model',
    tables => NULL,
    r2rml_table_owner => 'SCOTT',
    r2rml_table_name => 'R2RTAB'
  );
END;
/

例9-4 R2RMLマッピング文字列によるRDFビューの作成

次の例に示すように、R2RML文字列から直接RDFビューを作成することもできます。

DECLARE
  r2rmlStr CLOB;

BEGIN

  r2rmlStr := 
   '@prefix rr: <http://www.w3.org/ns/r2rml#>. '||
   '@prefix xsd: <http://www.w3.org/2001/XMLSchema#>. '||
   '@prefix ex: <http://example.com/ns#>. '||'

    ex:TriplesMap_Dept
        rr:logicalTable [ rr:tableName "DEPT" ];
        rr:subjectMap [
            rr:template "http://data.example.com/department/{DEPTNO}";
            rr:class ex:Department;
        ];
        rr:predicateObjectMap [
            rr:predicate ex:deptNum;
            rr:objectMap [ rr:column "DEPTNO" ; rr:datatype xsd:integer ];
        ];
        rr:predicateObjectMap [
            rr:predicate ex:deptName;
            rr:objectMap [ rr:column "DNAME" ];
        ];
        rr:predicateObjectMap [
            rr:predicate ex:deptLocation;
            rr:objectMap [ rr:column "LOC" ];
        ].'||'

    ex:TriplesMap_Emp
        rr:logicalTable [ rr:tableName "EMP" ];
        rr:subjectMap [
            rr:template "http://data.example.com/employee/{EMPNO}";
            rr:class ex:Employee;
        ];
        rr:predicateObjectMap [
            rr:predicate ex:empNum;
            rr:objectMap [ rr:column "EMPNO" ; rr:datatype xsd:integer ];
        ];
        rr:predicateObjectMap [
            rr:predicate ex:empName;
            rr:objectMap [ rr:column "ENAME" ];
        ];
        rr:predicateObjectMap [
            rr:predicate ex:jobType;
            rr:objectMap [ rr:column "JOB" ];
        ];
        rr:predicateObjectMap [
            rr:predicate ex:worksForDeptNum;
            rr:objectMap [ rr:column "DEPTNO" ; rr:dataType xsd:integer ];
        ];
        rr:predicateObjectMap [
            rr:predicate ex:worksForDept;
            rr:objectMap [ 
              rr:parentTriplesMap ex:TriplesMap_Dept ; 
              rr:joinCondition [ rr:child "DEPTNO"; rr:parent "DEPTNO" ]]].';

  sem_apis.create_rdfview_model(
    model_name => 'empdb_model',
    tables => NULL,
    r2rml_string => r2rmlStr,
    r2rml_string_fmt => 'TURTLE'
  );

END;
/

9.2.3 RDFビューの削除

例9-5に示すように、RDFビューは、SEM_APIS.DROP_RDFVIEW_MODELプロシージャを使用して削除できます。

例9-5 RDFビューの削除

BEGIN
  sem_apis.drop_rdfview_model(
    model_name => 'empdb_model'
  );
END;
/

9.2.4 RDFビューからステージング表への仮想コンテンツのエクスポート

RDFビューのコンテンツは仮想、つまり直接マッピングまたはR2RMLマッピングによってマップされ、基礎となるリレーショナル・データに対応するRDFトリプルであり、実体はなく、どこにも格納されていません。ただしテストのために、これらの仮想RDFトリプルをRDFモデルに具体化し、格納する必要がある場合があります。SEM_APIS.EXPORT_RDFVIEW_MODELサブプログラムは、RDFビューのRDFトリプルをステージング表に格納します。その後、ステージング表を使用してRDFモデルへロードすることができます。

例9-6では、RDFビューempdb_modelのコンテンツをステージング表SCOTT.RDFTABに実体化(N-Triples形式)します。

例9-6 RDFビューのエクスポート

BEGIN
  sem_apis.export_rdfview_model(
    model_name => 'empdb_model',
    rdf_table_owner => 'SCOTT',
    rdf_table_name => 'RDFTAB'
  );
END;

9.3 例: 直接マッピングを使用したRDFビューの作成

ここでは、直接マッピングを使用したRDFビューの使用例を示します。

例9-7は、直接マッピングによるRDFビューを使用した単純なワークフローを示しています。ここでは、次のことを行っています。

  1. 2つのリレーショナル表(EMPおよびDEPT)を作成します。

  2. 表にデータを挿入します。

  3. 2つの表の直接マッピングを使用して、RDFビュー・モデル(empdb_model)を作成します。

  4. SEM_MATCHベースのSQL問合せで、SPARQLを使用してRDFビューを問い合せます。

例9-8に、例9-7の文による出力を示します。

例9-7 直接マッピングによるRDFビューの使用

-- Use the following relational tables.
 
CREATE TABLE dept (
  deptno NUMBER CONSTRAINT pk_DeptTab_deptno PRIMARY KEY,
  dname VARCHAR2(30),
  loc VARCHAR2(30)
);
 
CREATE TABLE emp ( 
  empno NUMBER PRIMARY KEY,
  ename VARCHAR2(30),
  job VARCHAR2(20),
  deptno NUMBER REFERENCES dept (deptno)
);
 
-- Insert some data.
 
INSERT INTO dept (deptno, dname, loc)
  VALUES (1, 'Sales', 'Boston');
INSERT INTO dept (deptno, dname, loc)
  VALUES (2, 'Manufacturing', 'Chicago');
INSERT INTO dept (deptno, dname, loc)
  VALUES (3, 'Marketing', 'Boston');
 
INSERT INTO emp (empno, ename, job, deptno)
  VALUES (1, 'Alvarez', 'SalesRep', 1);
INSERT INTO emp (empno, ename, job, deptno)
  VALUES (2, 'Baxter', 'Supervisor', 2);
INSERT INTO emp (empno, ename, job, deptno)
  VALUES (3, 'Chen', 'Writer', 3);
INSERT INTO emp (empno, ename, job, deptno)
  VALUES (4, 'Davis', 'Technician', 2);
 
-- Create an RDF view model using direct mapping of two tables, EMP and DEPT, 
-- with a base prefix of http://empdb/.
-- Specify KEY_BASED_REF_PROPERTY=T for the options parameter.
 
BEGIN
  sem_apis.create_rdfview_model(
    model_name => 'empdb_model',
    tables => SYS.ODCIVarchar2List('EMP', 'DEPT'),
    prefix => 'http://empdb/',
    options => 'KEY_BASED_REF_PROPERTY=T'
  );
END;
/
 
-- Query an RDF view using SPARQL in a SEM_MATCH-based SQL query. 
-- The next statament is a query against an RDF view named empdb_model 
-- to find the employees who work for any department located in Boston.

SELECT emp
  FROM TABLE(SEM_MATCH(
  '{?emp emp:ref-DEPTNO ?dept . ?dept dept:LOC "Boston"}',
  SEM_Models('empdb_model'),
  NULL,
  SEM_ALIASES(
    SEM_ALIAS('dept','http://empdb/TESTUSER.DEPT#'),
    SEM_ALIAS('emp','http://empdb/TESTUSER.EMP#')
  ),
  null));

-- The preceding query is functionally comparable to this:
SELECT e.empno FROM emp e, dept d WHERE e.deptno = d.deptno AND d.loc = 'Boston';

例9-8 例9-7の出力

SQL> -- Use the following relational tables.
SQL> 
SQL> CREATE TABLE dept (
  2    deptno NUMBER CONSTRAINT pk_DeptTab_deptno PRIMARY KEY,
  3    dname VARCHAR2(30),
  4    loc VARCHAR2(30)
  5  );
 
Table created.
 
SQL> 
SQL> CREATE TABLE emp (
  2    empno NUMBER PRIMARY KEY,
  3    ename VARCHAR2(30),
  4    job VARCHAR2(20),
  5    deptno NUMBER REFERENCES dept (deptno)
  6  );
 
Table created.
 
SQL> 
SQL> -- Insert some data.
SQL> 
SQL> INSERT INTO dept (deptno, dname, loc)
  2    VALUES (1, 'Sales', 'Boston');
 
1 row created.
 
SQL> INSERT INTO dept (deptno, dname, loc)
  2    VALUES (2, 'Manufacturing', 'Chicago');
 
1 row created.
 
SQL> INSERT INTO dept (deptno, dname, loc)
  2    VALUES (3, 'Marketing', 'Boston');
 
1 row created.
 
SQL> 
SQL> INSERT INTO emp (empno, ename, job, deptno)
  2    VALUES (1, 'Alvarez', 'SalesRep', 1);
 
1 row created.
 
SQL> INSERT INTO emp (empno, ename, job, deptno)
  2    VALUES (2, 'Baxter', 'Supervisor', 2);
 
1 row created.
 
SQL> INSERT INTO emp (empno, ename, job, deptno)
  2    VALUES (3, 'Chen', 'Writer', 3);
 
1 row created.
 
SQL> INSERT INTO emp (empno, ename, job, deptno)
  2    VALUES (4, 'Davis', 'Technician', 2);
 
1 row created.
 
SQL> 
SQL> -- Create an RDF view model using direct mapping of two tables, EMP and DEPT,
SQL> -- with a base prefix of http://empdb/.
SQL> -- Specify KEY_BASED_REF_PROPERTY=T for the options parameter.
SQL> 
SQL> BEGIN
  2    sem_apis.create_rdfview_model(
  3  	 model_name => 'empdb_model',
  4  	 tables => SYS.ODCIVarchar2List('EMP', 'DEPT'),
  5  	 prefix => 'http://empdb/',
  6  	 options => 'KEY_BASED_REF_PROPERTY=T'
  7    );
  8  END;
  9  /
 
PL/SQL procedure successfully completed.
 
SQL> 
SQL> -- Query an RDF view using SPARQL in a SEM_MATCH-based SQL query.
SQL> -- The next statament is a query against an RDF view named empdb_model
SQL> -- to find the employees who work for any department located in Boston.
SQL> 
SQL> SELECT emp
  2    FROM TABLE(SEM_MATCH(
  3  	 '{?emp emp:ref-DEPTNO ?dept . ?dept dept:LOC "Boston"}',
  4  	 SEM_Models('empdb_model'),
  5  	 NULL,
  6  	 SEM_ALIASES(
  7  	   SEM_ALIAS('dept','http://empdb/TESTUSER.DEPT#'),
  8  	   SEM_ALIAS('emp','http://empdb/TESTUSER.EMP#')
  9  	 ),
 10  	 null));
 
EMP                                                                             
--------------------------------------------------------------------------------
http://empdb/TESTUSER.EMP/EMPNO=1                                               
http://empdb/TESTUSER.EMP/EMPNO=3                                               
 
SQL> 
SQL> -- The preceding query is functionally comparable to this:
SQL> SELECT e.empno FROM emp e, dept d WHERE e.deptno = d.deptno AND d.loc = 'Boston';
 
     EMPNO                                                                      
----------                                                                      
         1                                                                      
         3  

9.4 ネイティブRDFデータと仮想RDB2RDFデータの組合せ

SERVICEキーワードを使用して、ネイティブ・トリプル・データと仮想RDB2RDFトリプル・データを、1つのSEM_MATCH問合せで組み合せることができます。

SERVICEキーワード(「グラフ・パターン: SPARQL 1.1のフェデレーテッド問合せのサポート」を参照)は、ローカル(仮想)のRDFデータを示す特別なSERVICE URLの使用を通じてオーバーロードされます。特別なSERVICE URLを表すために次の接頭辞が使用されます。

  • ネイティブ・モデル - oram: <http://xmlns.oracle.com/models/>

  • ネイティブ仮想モデル - oravm: <http://xmlns.oracle.com/virtual_models/>

  • RDB2RDFモデル - orardbm: <http://xmlns.oracle.com/rdb_models/>

例9-9 複数のデータ・セットの問合せ

例9-9は複数のデータ・セットを問い合せます。この問合せでは、最初のトリプル・パターン{ ?x rdf:type :Person }は通常どおりネイティブ・モデルm1に対応しますが、{ ?x :name ?name }はローカル・ネイティブ・モデルm2に対応し、{ ?x :email ?email }はローカルRDB2RDFモデルrdfview1に対応します。

select * from table (sem_match(
'SELECT ?x ?name ?email
 WHERE {
  ?x rdf:type :Person .
  OPTIONAL { SERVICE oram:m2 { ?x :name ?name } }
  OPTIONAL { SERVICE orardbm:rdfview1 { ?x :email ?email } }
}'
sem_models('m1'), null, null, null, null, ' '));

オーバーロードされたSERVICEの使用は、SEM_MATCHのmodels引数に指定された1つのモデルのみで許可されます。オーバーロードされたSERVICE問合せでは、複数のモデルまたは入力としてのルールベースは許可されません。そのような組合せのかわりに、複数のモデルまたは伴意(あるいは両方)を含む仮想モデルを使用する必要があります。また、SEM_MATCHのindex_status引数は、modelsパラメータで入力として渡された仮想モデルに含まれる伴意のみをチェックします。つまり、オーバーロードされたSERVICEコールで参照される伴意のステータスはチェックされません。

例9-10 仮想RDB2RDFデータとネイティブRDFデータの問合せ

例9-10では、2つのデータ・セット、つまり例9-7empdb_modelと、peopleという名前のネイティブ・モデルに対して問合せを行っています。

-- Create native model people --
create table atab (gval varchar2(4000), tri sdo_rdf_triple_s);
 
execute sem_apis.create_sem_model('people','atab','tri');
 
create table stab(RDF$STC_GRAPH varchar2(4000), RDF$STC_sub varchar2(4000),
                  RDF$STC_pred varchar2(4000), RDF$STC_obj varchar2(4000));
grant select on stab to mdsys;
grant insert on atab to mdsys;
 
insert into stab values (null, '<http://empdb/TESTUSER.EMP/EMPNO=1>', '<http://people.org/age>', '"35"^^<http://www.w3.org/2001/XMLSchema#int>');
insert into stab values (null, '<http://empdb/TESTUSER.EMP/EMPNO=2>', '<http://people.org/age>', '"39"^^<http://www.w3.org/2001/XMLSchema#int>');
insert into stab values (null, '<http://empdb/TESTUSER.EMP/EMPNO=3>', '<http://people.org/age>', '"30"^^<http://www.w3.org/2001/XMLSchema#int>');
insert into stab values (null, '<http://empdb/TESTUSER.EMP/EMPNO=4>', '<http://people.org/age>', '"42"^^<http://www.w3.org/2001/XMLSchema#int>');
commit;
 
exec sem_apis.bulk_load_from_staging_table('people','testuser','stab');
 
-- Querying multiple datasets --
SELECT emp, age
  FROM TABLE(SEM_MATCH(
    'SELECT ?emp ?age WHERE{
       ?emp peop:age ?age
       SERVICE orardbm:empdb_model { ?emp emp:ref-DEPTNO ?dept . ?dept dept:LOC "Boston" }
    }',
    SEM_Models('people'),
    NULL,
    SEM_ALIASES(
          SEM_ALIAS('dept','http://empdb/TESTUSER.DEPT#'),
          SEM_ALIAS('emp','http://empdb/TESTUSER.EMP#'),
          SEM_ALIAS('peop','http://people.org/')
        ),
    NULL));

9.4.1 オーバーロードしたサービスによるネストされたループのプッシュダウン

シナリオによっては、ネストしたループのサービスを使用することで、パフォーマンスが向上することがあります。複数のデータ・セットに対する問合せを行って、35歳の人が所属している部すべてのプロパティを調べる、次のような例を考えます。

SELECT emp, dept, p, o
  FROM TABLE(SEM_MATCH(
    'SELECT * WHERE{
       ?emp peop:age 35
       SERVICE orardbm:empdb_model{ ?emp emp:ref-DEPTNO ?dept . ?dept ?p ?o }
    }',
    SEM_Models('people'),
    NULL,
    SEM_ALIASES(
          SEM_ALIAS('dept','http://empdb/TESTUSER.DEPT#'),
          SEM_ALIAS('emp','http://empdb/TESTUSER.EMP#'),
          SEM_ALIAS('peop','http://people.org/')
        ),
    NULL));

与えられたグラフ・パターンと一致するすべての結果を得るために、最初にモデルpeopleに対してトリプル{ ?emp peop:age 35 }の照合が行われ、次にモデルempdb_modelに対してトリプル{ ?emp emp:ref-DEPTNO ?d . ?d dept:DNAME ?dept }の照合が行われ、最後に2つの照合結果が結合されます。ここで、モデルpeopleには35歳の人が1人しかいないものの、部に関する情報を含むトリプルは10万個あるとします。明らかに、すべての結果を抽出する方法は最も効率的とはいえず、問合せのパフォーマンスも悪いと考えられます。なぜなら、問合せの残りの部分と結合する前に、大量の結果を処理する必要があるためです。

この例では、ネストしたループのサービスでパフォーマンスが向上する可能性があります。ヒントOVERLOADED_NL=Tが使用されると、問合せの最初の部分で得られる結果が計算され、SERVICEパターンが、ルート・トリプル・パターンから得られる?emp値ごとに1回ずつ、ネストしたループで順番に実行されます。実行のたびに、SERVICEパターンの主語値?empが、ルート・トリプル・パターンの定数に置き換えられます。これにより、結合条件が効率的にSERVICE句へプッシュ・ダウンされます。

次の例では、先の問合せに対してヒントOVERLOADED_NL=Tが使用されています。

SELECT emp, dept, p, o
  FROM TABLE(SEM_MATCH(
    'SELECT * WHERE{
       ?emp peop:age 35
       SERVICE orardbm:empdb_model { ?emp emp:ref-DEPTNO ?dept . ?dept ?p ?o }
    }',
    SEM_Models('people'),
    NULL,
    SEM_ALIASES(
          SEM_ALIAS('dept','http://empdb/TESTUSER.DEPT#'),
          SEM_ALIAS('emp','http://empdb/TESTUSER.EMP#'),
          SEM_ALIAS('peop','http://people.org/')
        ),
    NULL,null,' OVERLOADED_NL=T '));

ヒントOVERLOADED_NL=Tは、SEM_MATCHオプションや、与えられたSERVICEグラフのインライン・コメントで指定することができます。