Oracle - 动态 SQL/XMLTable 性能不佳
Oracle - Dynamic SQL / XMLTable Poor Performance
我在列 (DYNAMIC_SQL
) 中包含一系列 'dynamic' SQL 查询,'dynamic' 查询本身相当基础;
例如
SELECT ROWID AS RECORD_ID, COLUMN_1 AS STR_VALUE, '-Undefined-' AS STR_IDENTIFIER_VALUE, 'DS_1319' AS DS_TABLE_NAME FROM DS_1319
然后我结合使用 XMLTABLE
和 GETXML
来提取和显示结果。
但是,即使查询运行并按预期运行,我注意到性能非常差(注意:DS_1319
的行数为;13,939)。
我使用的查询如下:
SELECT
T1.*,
T2.RECORD_ID,
T2.STR_VALUE,
T2.STR_IDENTIFIER_VALUE
FROM
CP_RDN_IN_DYNAMIC_SQL_TMP T1,
XMLTABLE('/ROWSET /ROW'
PASSING XMLTYPE(DBMS_XMLGEN.GETXML(T1.DYNAMIC_SQL))
COLUMNS RECORD_ID VARCHAR2(255) PATH 'RECORD_ID',
STR_VALUE VARCHAR2(255) PATH 'STR_VALUE',
STR_IDENTIFIER_VALUE VARCHAR2(255) PATH 'STR_IDENTIFIER_VALUE',
DS_TABLE_NAME VARCHAR2(255) PATH 'DS_TABLE_NAME') T2
WHERE
T1.DS_TABLE_NAME = T2.DS_TABLE_NAME
注意:DYNAMIC_SQL
列定义如下;
'SELECT ROWID AS RECORD_ID, '||
T1.FIELD_NAME||' AS STR_VALUE, '||
T1.IDENTIFIER_FIELD_NAME||' AS STR_IDENTIFIER_VALUE, '''||
T1.DS_TABLE_NAME||''' AS DS_TABLE_NAME
FROM'||T1.DS_TABLE_NAME AS DYNAMIC_SQL
以下是一小部分数据;
<?xml version="1.0"?>
<ROWSET>
<ROW>
<RECORD_ID>AAAGU2AABAAAShJAAA</RECORD_ID>
<STR_VALUE>ORACLE</STR_VALUE>
<STR_IDENTIFIER_VALUE>-Undefined-</STR_IDENTIFIER_VALUE>
<DS_TABLE_NAME>DS_1319</DS_TABLE_NAME>
</ROW>
<ROW>
<RECORD_ID>AAAGU2AABAAAShJAAB</RECORD_ID>
<STR_VALUE>Oracle</STR_VALUE>
<STR_IDENTIFIER_VALUE>-Undefined-</STR_IDENTIFIER_VALUE>
<DS_TABLE_NAME>DS_1319</DS_TABLE_NAME>
</ROW>
<ROW>
<RECORD_ID>AAAGU2AABAAAShJAAC</RECORD_ID>
<STR_VALUE>Oracle 9i</STR_VALUE>
<STR_IDENTIFIER_VALUE>-Undefined-</STR_IDENTIFIER_VALUE>
<DS_TABLE_NAME>DS_1319</DS_TABLE_NAME>
</ROW>
<ROW>
<RECORD_ID>AAAGU2AABAAAShJAAD</RECORD_ID>
<STR_VALUE>Oracle 11g</STR_VALUE>
<STR_IDENTIFIER_VALUE>-Undefined-</STR_IDENTIFIER_VALUE>
<DS_TABLE_NAME>DS_1319</DS_TABLE_NAME>
</ROW>
<ROW>
<RECORD_ID>AAAGU2AABAAAShJAAE</RECORD_ID>
<STR_VALUE>Oracle CRM</STR_VALUE>
<STR_IDENTIFIER_VALUE>-Undefined-</STR_IDENTIFIER_VALUE>
<DS_TABLE_NAME>DS_1319</DS_TABLE_NAME>
</ROW>
<ROW>
<RECORD_ID>AAAGU2AABAAAShJAAF</RECORD_ID>
<STR_VALUE>oracle 10g</STR_VALUE>
<STR_IDENTIFIER_VALUE>-Undefined-</STR_IDENTIFIER_VALUE>
<DS_TABLE_NAME>DS_1319</DS_TABLE_NAME>
</ROW>
<ROW>
<RECORD_ID>AAAGU2AABAAAShJAAG</RECORD_ID>
<STR_VALUE>ORACLE, XE</STR_VALUE>
<STR_IDENTIFIER_VALUE>-Undefined-</STR_IDENTIFIER_VALUE>
<DS_TABLE_NAME>DS_1319</DS_TABLE_NAME>
</ROW>
<ROW>
<RECORD_ID>AAAGU2AABAAAShJAAH</RECORD_ID>
<STR_VALUE>XE</STR_VALUE>
<STR_IDENTIFIER_VALUE>-Undefined-</STR_IDENTIFIER_VALUE>
<DS_TABLE_NAME>DS_1319</DS_TABLE_NAME>
</ROW>
<ROW>
<RECORD_ID>AAAGU2AABAAAShJAAI</RECORD_ID>
<STR_VALUE>MS Windows</STR_VALUE>
<STR_IDENTIFIER_VALUE>-Undefined-</STR_IDENTIFIER_VALUE>
<DS_TABLE_NAME>DS_1319</DS_TABLE_NAME>
</ROW>
<ROW>
<RECORD_ID>AAAGU2AABAAAShJAAJ</RECORD_ID>
<STR_VALUE>Microsoft Windows Vista</STR_VALUE>
<STR_IDENTIFIER_VALUE>-Undefined-</STR_IDENTIFIER_VALUE>
<DS_TABLE_NAME>DS_1319</DS_TABLE_NAME>
</ROW>
<ROW>
<RECORD_ID>AAAGU2AABAAAShJAAK</RECORD_ID>
<STR_VALUE>Vista</STR_VALUE>
<STR_IDENTIFIER_VALUE>-Undefined-</STR_IDENTIFIER_VALUE>
<DS_TABLE_NAME>DS_1319</DS_TABLE_NAME>
</ROW>
<ROW>
<RECORD_ID>AAAGU2AABAAAShJAAL</RECORD_ID>
<STR_VALUE>MSOFT Win Vista</STR_VALUE>
<STR_IDENTIFIER_VALUE>-Undefined-</STR_IDENTIFIER_VALUE>
<DS_TABLE_NAME>DS_1319</DS_TABLE_NAME>
</ROW>
<ROW>
<RECORD_ID>AAAGU2AABAAAShJAAM</RECORD_ID>
<STR_VALUE>Microsoft Office</STR_VALUE>
<STR_IDENTIFIER_VALUE>-Undefined-</STR_IDENTIFIER_VALUE>
<DS_TABLE_NAME>DS_1319</DS_TABLE_NAME>
</ROW>
<ROW>
<RECORD_ID>AAAGU2AABAAAShJAAN</RECORD_ID>
<STR_VALUE>MS SQL Server</STR_VALUE>
<STR_IDENTIFIER_VALUE>-Undefined-</STR_IDENTIFIER_VALUE>
<DS_TABLE_NAME>DS_1319</DS_TABLE_NAME>
</ROW>
<ROW>
<RECORD_ID>AAAGU2AABAAAShJAAO</RECORD_ID>
<STR_VALUE>VISTA MS WINDOWS</STR_VALUE>
<STR_IDENTIFIER_VALUE>-Undefined-</STR_IDENTIFIER_VALUE>
<DS_TABLE_NAME>DS_1319</DS_TABLE_NAME>
</ROW>
<ROW>
<RECORD_ID>AAAGU2AABAAAShJAAP</RECORD_ID>
<STR_VALUE>Windows vista</STR_VALUE>
<STR_IDENTIFIER_VALUE>-Undefined-</STR_IDENTIFIER_VALUE>
<DS_TABLE_NAME>DS_1319</DS_TABLE_NAME>
</ROW>
<ROW>
<RECORD_ID>AAAGU2AABAAAShJAAQ</RECORD_ID>
<STR_VALUE>Microsoft Windows 2000</STR_VALUE>
<STR_IDENTIFIER_VALUE>-Undefined-</STR_IDENTIFIER_VALUE>
<DS_TABLE_NAME>DS_1319</DS_TABLE_NAME>
</ROW>
<ROW>
<RECORD_ID>AAAGU2AABAAAShJAAR</RECORD_ID>
<STR_VALUE>Macromedia</STR_VALUE>
<STR_IDENTIFIER_VALUE>-Undefined-</STR_IDENTIFIER_VALUE>
<DS_TABLE_NAME>DS_1319</DS_TABLE_NAME>
</ROW>
</ROWSET>
我相当肯定有一种更有效的方法可以达到预期的结果,所以如果有任何脑洞大开的人提出一些意见/建议,我们将不胜感激(我愿意接受; 纯 SQL, PL/SQL, 等).
非常感谢。
我看不出有什么理由把结果转成XML,直接make dynamic SELECT就可以了
cur SYS_REFCURSOR;
BEGIN
DYNAMIC_SQL := 'SELECT ROWID AS RECORD_ID, '||
T1.FIELD_NAME||' AS STR_VALUE, '||
T1.IDENTIFIER_FIELD_NAME||' AS STR_IDENTIFIER_VALUE, '''||
T1.DS_TABLE_NAME||''' AS DS_TABLE_NAME
FROM'||T1.DS_TABLE_NAME;
OPEN CURSOR cur FOR DYNAMIC_SQL;
FETCH ...
我在列 (DYNAMIC_SQL
) 中包含一系列 'dynamic' SQL 查询,'dynamic' 查询本身相当基础;
例如
SELECT ROWID AS RECORD_ID, COLUMN_1 AS STR_VALUE, '-Undefined-' AS STR_IDENTIFIER_VALUE, 'DS_1319' AS DS_TABLE_NAME FROM DS_1319
然后我结合使用 XMLTABLE
和 GETXML
来提取和显示结果。
但是,即使查询运行并按预期运行,我注意到性能非常差(注意:DS_1319
的行数为;13,939)。
我使用的查询如下:
SELECT
T1.*,
T2.RECORD_ID,
T2.STR_VALUE,
T2.STR_IDENTIFIER_VALUE
FROM
CP_RDN_IN_DYNAMIC_SQL_TMP T1,
XMLTABLE('/ROWSET /ROW'
PASSING XMLTYPE(DBMS_XMLGEN.GETXML(T1.DYNAMIC_SQL))
COLUMNS RECORD_ID VARCHAR2(255) PATH 'RECORD_ID',
STR_VALUE VARCHAR2(255) PATH 'STR_VALUE',
STR_IDENTIFIER_VALUE VARCHAR2(255) PATH 'STR_IDENTIFIER_VALUE',
DS_TABLE_NAME VARCHAR2(255) PATH 'DS_TABLE_NAME') T2
WHERE
T1.DS_TABLE_NAME = T2.DS_TABLE_NAME
注意:DYNAMIC_SQL
列定义如下;
'SELECT ROWID AS RECORD_ID, '||
T1.FIELD_NAME||' AS STR_VALUE, '||
T1.IDENTIFIER_FIELD_NAME||' AS STR_IDENTIFIER_VALUE, '''||
T1.DS_TABLE_NAME||''' AS DS_TABLE_NAME
FROM'||T1.DS_TABLE_NAME AS DYNAMIC_SQL
以下是一小部分数据;
<?xml version="1.0"?>
<ROWSET>
<ROW>
<RECORD_ID>AAAGU2AABAAAShJAAA</RECORD_ID>
<STR_VALUE>ORACLE</STR_VALUE>
<STR_IDENTIFIER_VALUE>-Undefined-</STR_IDENTIFIER_VALUE>
<DS_TABLE_NAME>DS_1319</DS_TABLE_NAME>
</ROW>
<ROW>
<RECORD_ID>AAAGU2AABAAAShJAAB</RECORD_ID>
<STR_VALUE>Oracle</STR_VALUE>
<STR_IDENTIFIER_VALUE>-Undefined-</STR_IDENTIFIER_VALUE>
<DS_TABLE_NAME>DS_1319</DS_TABLE_NAME>
</ROW>
<ROW>
<RECORD_ID>AAAGU2AABAAAShJAAC</RECORD_ID>
<STR_VALUE>Oracle 9i</STR_VALUE>
<STR_IDENTIFIER_VALUE>-Undefined-</STR_IDENTIFIER_VALUE>
<DS_TABLE_NAME>DS_1319</DS_TABLE_NAME>
</ROW>
<ROW>
<RECORD_ID>AAAGU2AABAAAShJAAD</RECORD_ID>
<STR_VALUE>Oracle 11g</STR_VALUE>
<STR_IDENTIFIER_VALUE>-Undefined-</STR_IDENTIFIER_VALUE>
<DS_TABLE_NAME>DS_1319</DS_TABLE_NAME>
</ROW>
<ROW>
<RECORD_ID>AAAGU2AABAAAShJAAE</RECORD_ID>
<STR_VALUE>Oracle CRM</STR_VALUE>
<STR_IDENTIFIER_VALUE>-Undefined-</STR_IDENTIFIER_VALUE>
<DS_TABLE_NAME>DS_1319</DS_TABLE_NAME>
</ROW>
<ROW>
<RECORD_ID>AAAGU2AABAAAShJAAF</RECORD_ID>
<STR_VALUE>oracle 10g</STR_VALUE>
<STR_IDENTIFIER_VALUE>-Undefined-</STR_IDENTIFIER_VALUE>
<DS_TABLE_NAME>DS_1319</DS_TABLE_NAME>
</ROW>
<ROW>
<RECORD_ID>AAAGU2AABAAAShJAAG</RECORD_ID>
<STR_VALUE>ORACLE, XE</STR_VALUE>
<STR_IDENTIFIER_VALUE>-Undefined-</STR_IDENTIFIER_VALUE>
<DS_TABLE_NAME>DS_1319</DS_TABLE_NAME>
</ROW>
<ROW>
<RECORD_ID>AAAGU2AABAAAShJAAH</RECORD_ID>
<STR_VALUE>XE</STR_VALUE>
<STR_IDENTIFIER_VALUE>-Undefined-</STR_IDENTIFIER_VALUE>
<DS_TABLE_NAME>DS_1319</DS_TABLE_NAME>
</ROW>
<ROW>
<RECORD_ID>AAAGU2AABAAAShJAAI</RECORD_ID>
<STR_VALUE>MS Windows</STR_VALUE>
<STR_IDENTIFIER_VALUE>-Undefined-</STR_IDENTIFIER_VALUE>
<DS_TABLE_NAME>DS_1319</DS_TABLE_NAME>
</ROW>
<ROW>
<RECORD_ID>AAAGU2AABAAAShJAAJ</RECORD_ID>
<STR_VALUE>Microsoft Windows Vista</STR_VALUE>
<STR_IDENTIFIER_VALUE>-Undefined-</STR_IDENTIFIER_VALUE>
<DS_TABLE_NAME>DS_1319</DS_TABLE_NAME>
</ROW>
<ROW>
<RECORD_ID>AAAGU2AABAAAShJAAK</RECORD_ID>
<STR_VALUE>Vista</STR_VALUE>
<STR_IDENTIFIER_VALUE>-Undefined-</STR_IDENTIFIER_VALUE>
<DS_TABLE_NAME>DS_1319</DS_TABLE_NAME>
</ROW>
<ROW>
<RECORD_ID>AAAGU2AABAAAShJAAL</RECORD_ID>
<STR_VALUE>MSOFT Win Vista</STR_VALUE>
<STR_IDENTIFIER_VALUE>-Undefined-</STR_IDENTIFIER_VALUE>
<DS_TABLE_NAME>DS_1319</DS_TABLE_NAME>
</ROW>
<ROW>
<RECORD_ID>AAAGU2AABAAAShJAAM</RECORD_ID>
<STR_VALUE>Microsoft Office</STR_VALUE>
<STR_IDENTIFIER_VALUE>-Undefined-</STR_IDENTIFIER_VALUE>
<DS_TABLE_NAME>DS_1319</DS_TABLE_NAME>
</ROW>
<ROW>
<RECORD_ID>AAAGU2AABAAAShJAAN</RECORD_ID>
<STR_VALUE>MS SQL Server</STR_VALUE>
<STR_IDENTIFIER_VALUE>-Undefined-</STR_IDENTIFIER_VALUE>
<DS_TABLE_NAME>DS_1319</DS_TABLE_NAME>
</ROW>
<ROW>
<RECORD_ID>AAAGU2AABAAAShJAAO</RECORD_ID>
<STR_VALUE>VISTA MS WINDOWS</STR_VALUE>
<STR_IDENTIFIER_VALUE>-Undefined-</STR_IDENTIFIER_VALUE>
<DS_TABLE_NAME>DS_1319</DS_TABLE_NAME>
</ROW>
<ROW>
<RECORD_ID>AAAGU2AABAAAShJAAP</RECORD_ID>
<STR_VALUE>Windows vista</STR_VALUE>
<STR_IDENTIFIER_VALUE>-Undefined-</STR_IDENTIFIER_VALUE>
<DS_TABLE_NAME>DS_1319</DS_TABLE_NAME>
</ROW>
<ROW>
<RECORD_ID>AAAGU2AABAAAShJAAQ</RECORD_ID>
<STR_VALUE>Microsoft Windows 2000</STR_VALUE>
<STR_IDENTIFIER_VALUE>-Undefined-</STR_IDENTIFIER_VALUE>
<DS_TABLE_NAME>DS_1319</DS_TABLE_NAME>
</ROW>
<ROW>
<RECORD_ID>AAAGU2AABAAAShJAAR</RECORD_ID>
<STR_VALUE>Macromedia</STR_VALUE>
<STR_IDENTIFIER_VALUE>-Undefined-</STR_IDENTIFIER_VALUE>
<DS_TABLE_NAME>DS_1319</DS_TABLE_NAME>
</ROW>
</ROWSET>
我相当肯定有一种更有效的方法可以达到预期的结果,所以如果有任何脑洞大开的人提出一些意见/建议,我们将不胜感激(我愿意接受; 纯 SQL, PL/SQL, 等).
非常感谢。
我看不出有什么理由把结果转成XML,直接make dynamic SELECT就可以了
cur SYS_REFCURSOR;
BEGIN
DYNAMIC_SQL := 'SELECT ROWID AS RECORD_ID, '||
T1.FIELD_NAME||' AS STR_VALUE, '||
T1.IDENTIFIER_FIELD_NAME||' AS STR_IDENTIFIER_VALUE, '''||
T1.DS_TABLE_NAME||''' AS DS_TABLE_NAME
FROM'||T1.DS_TABLE_NAME;
OPEN CURSOR cur FOR DYNAMIC_SQL;
FETCH ...