- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我在 Oracle 11g 文档和论坛中搜索了有关如何获取此 View 和查询以使用基于函数的索引的示例,但到目前为止我一无所获。感谢任何帮助。
我使用的应用程序不支持直接查询的 TIMESTAMP 数据类型,但支持在 View 中将其转换为 DATE 的数据类型。但是,我随后必须使用时间戳函数查询此转换列。这有点往返。第 3 方应用程序发送与我在 SQL*Plus/SQL Developer 中使用的相同的查询并显示在下方。
我实际上并不需要 TIMESTAMP 数据类型的小数秒粒度,只是出于数据供应商的原因需要在该数据库中使用它。
据我所知,当函数应用于该列时,不会使用列索引。我无法完成的是构建一个适当的基于函数的索引来避免对数百万行(在 200 万到 6 亿行之间,具体取决于表)进行全表扫描。我不想使用提示,但在这一点上,任何事情都比全表扫描好,我愿意接受所有建议。
这是所需的 View :
SELECT
CAST(SAMPLE_TABLE.TIMESTAMP_COLUMN as DATE) as TIMESTAMP_COLUMN
FROM TEST_USER.SAMPLE_TABLE;
这是一个带有解释计划前缀的示例查询:
explain plan for
select * FROM SAMPLE_VIEW WHERE TIMESTAMP_COLUMN = timestamp '2010-08-10 12:00:00';
select plan_table_output
from table(dbms_xplan.display('plan_table',null,'all'));
-----------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop |
-----------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 200K| 1562K| 169K (1)| 00:33:56 | | |
| 1 | PARTITION LIST ALL | | 200K| 1562K| 169K (1)| 00:33:56 | 1 | 6 |
| 2 | PARTITION RANGE ALL| | 200K| 1562K| 169K (1)| 00:33:56 | 1 | 49 |
|* 3 | TABLE ACCESS FULL | SAMPLE_TABLE | 200K| 1562K| 169K (1)| 00:33:56 | 1 | 294 |
-----------------------------------------------------------------------------------------------------
Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------
1 - SEL$F5BB74E1
3 - SEL$F5BB74E1 / SAMPLE_TABLE@SEL$2
Predicate Information (identified by operation id):
---------------------------------------------------
3 - filter(INTERNAL_FUNCTION(CAST(INTERNAL_FUNCTION("TIMESTAMP_COLUMN") AS DATE))=TIMESTAMP_COLUMN'
2010-08-10 12:00:00.000000000')
Column Projection Information (identified by operation id):
-----------------------------------------------------------
1 - "TIMESTAMP_COLUMN"[TIMESTAMP WITH LOCAL TIME ZONE,11]
2 - "TIMESTAMP_COLUMN"[TIMESTAMP WITH LOCAL TIME ZONE,11]
3 - "TIMESTAMP_COLUMN"[TIMESTAMP WITH LOCAL TIME ZONE,11]
当然,只要我从 View 中删除 Cast 函数,就会按预期使用索引:
改变的观点:
SELECT
TIMESTAMP_COLUMN
FROM TEST_USER.SAMPLE_TABLE;
相同的查询:
explain plan for
select * FROM SAMPLE_VIEW WHERE TIMESTAMP_COLUMN = timestamp '2010-08-10 12:00:00';
select plan_table_output
from table(dbms_xplan.display('plan_table',null,'all'));
------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 2 | 22 | 3 (0)| 00:00:01 |
|* 1 | INDEX RANGE SCAN| TIMESTAMP_COL_IDX | 2 | 22 | 3 (0)| 00:00:01 |
------------------------------------------------------------------------------------
Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------
1 - SEL$F5BB74E1 / SAMPLE_TABLE@SEL$2
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("TIMESTAMP_COLUMN"=TIMESTAMP' 2010-08-10 12:00:00.000000000')
Column Projection Information (identified by operation id):
-----------------------------------------------------------
1 - "TIMESTAMP_COLUMN"[TIMESTAMP WITH LOCAL TIME ZONE,11]
这是在没有转换函数的情况下使用的普通索引 DDL (TIMESTAMP_COL_IDX)。我使用 SQL Developer 的 GUI 构建了这个:
CREATE INDEX "TEST_USER"."TIMESTAMP_COL_IDX" ON "TEST_USER"."SAMPLE_TABLE" ("TIMESTAMP_COLUMN")
PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS
STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
TABLESPACE "TEST" ;
这是我无法调用并且可能编写不当的基于函数的索引 DDL:
CREATE INDEX "TEST_USER"."TIMESTAMP_FBI_IDX" ON "TEST_USER"."SAMPLE_TABLE" (CAST("TIMESTAMP_COLUMN" AS DATE))
PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS
STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
TABLESPACE "TEST" ;
我已经收集了 View 所基于的表的统计信息,但在 11g 中我认为在构建索引后这不是“必需的”。它没有改变执行计划。
谢谢。
编辑 #1
当我说:“但是,我必须使用时间戳函数查询这个 cast 列。这有点往返。”...
...我应该澄清我需要使用的整个工作流程,这是造成这种情况的原因。以下是按时间顺序排列的工作流程:
这就是我所说的数据“往返”的意思;数据库和 Web 应用程序都使用 TIMESTAMP,但发布到 Web 应用程序的中间件不能,从而导致这种导致全表扫描的昂贵转换场景。
最佳答案
正如 Jokke Heikkilä 所指出的,您正在使用时间戳值进行查询。这会导致比较的左侧(即 View 的日期列)隐式转换为与常量相同的数据类型。你正在有效地做:
select * FROM SAMPLE_VIEW
WHERE cast(TIMESTAMP_COLUMN as timestamp) = timestamp '2010-08-10 12:00:00';
...正如您已经指出的那样,当函数应用于列时不会使用索引。
如果您将右侧设为日期,则将使用索引:
explain plan for
select * FROM SAMPLE_VIEW
WHERE TIMESTAMP_COLUMN = cast(timestamp '2010-08-10 12:00:00' as date);
select plan_table_output
from table(dbms_xplan.display('plan_table',null,'all'));
----------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 9 | 1 (0)| 00:00:01 |
|* 1 | INDEX RANGE SCAN| TIMESTAMP_FBI_IDX | 1 | 9 | 1 (0)| 00:00:01 |
----------------------------------------------------------------------------------------
Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------
1 - SEL$F5BB74E1 / SAMPLE_TABLE@SEL$2
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access(CAST(INTERNAL_FUNCTION("TIMESTAMP_COLUMN") AS
date)=CAST(TIMESTAMP' 2010-08-10 12:00:00.000000000' AS date))
Column Projection Information (identified by operation id):
-----------------------------------------------------------
1 - CAST(INTERNAL_FUNCTION("TIMESTAMP_COLUMN") AS date)[DATE,7]
你不必投右手边,它只需要是一个日期;如果你正在寻找午夜那么你可以使用日期文字,否则你可以使用 to_date
:
WHERE TIMESTAMP_COLUMN = to_date('2010-08-10 12:00:00', 'YYYY-MM-DD HH24:MI:SS');
您好像说您正在使用的应用程序只支持日期,所以大概您无论如何都可以传递一个正确的日期值;虽然我对你说“然后我必须使用时间戳函数查询这个转换列”感到困惑,并且应用程序在它生成的查询中指定了时间戳文字,这似乎没有关系。
如果您需要能够按日期或时间戳数据类型进行查询,那么您可以在 View 中同时包含这两种数据:
CREATE OR REPLACE VIEW SAMPLE_VIEW AS
SELECT TIMESTAMP_COLUMN,
CAST(SAMPLE_TABLE.TIMESTAMP_COLUMN as DATE) as DATE_COLUMN
FROM TEST_USER.SAMPLE_TABLE;
然后在相关列中查询您所拥有的值的数据类型:
WHERE TIMESTAMP_COLUMN = timestamp '2010-08-10 12:00:00'
或
WHERE DATE_COLUMN = to_date('2010-08-10 12:00:00', 'YYYY-MM-DD HH24:MI:SS')
第一个将使用 timestamp_col_idx
,第二个将使用 timestamp_fbi_idx
。当然,您的选择列表也需要更改才能获得正确的列。
作为另一种可能的替代方案,如果您可以更改从仅限日期层发送的查询,您可以将其转换为时间戳并直接查询表:
select * FROM SAMPLE_TABLE
WHERE TIMESTAMP_COLUMN =
cast(to_date('2010-08-10 12:00:00', 'YYYY-MM-DD HH24:MI:SS') as timestamp);
.. 但这取决于查询的构建方式以及您提供日期值的方式。不过,在那种情况下,您不需要 View 或 FBI。
关于database - 是否可以为在 View 中转换为 DATE 的 TIMESTAMP 列构建基于 Oracle 函数的索引?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25438950/
我在使用 gradle 构建一个特定应用程序时遇到问题。该应用程序可以用 eclipse 编译和构建,它在平板电脑上运行良好。当我尝试使用 Gradle 构建它时,“compileDebugJava”
我有一个 C 程序,是一位离开的开发人员留给我的。我试图弄清楚他到底在做什么,并将软件重新安排成更合乎逻辑的东西,这样我就可以更轻松地构建它。我正在使用 CMake 构建,而他使用的是 Make。 有
我刚开始阅读“Pro Spring MVC with web flow”,它附带了一个我想遵循的代码示例。 我要什么 - 我想像书中那样构建应用程序,使用 Gradle 有什么问题 - 我没用过 Gr
我希望有人已经这样做了。我正在尝试为我的一个 angular 2 项目在 teamcity 中建立一个连续的构建。在做了一些研究之后,我按照以下步骤操作: 构建步骤 1:为 teamcity 安装 j
我有一个旧的 ASP.Net 网站解决方案,看起来像: 当我在 Visual Studio 中构建解决方案时,我得到以下输出: ------ Build started: Project: C:\..
我使用 gulp-usref、gulp-if、gulp-uglify、gulp-csso 和 gulp-file-include 来构建我的应用程序。除了 HTML 保持原样外,构建中的一切都运行良好
我正在使用 ionic2 开发内部移动应用程序。我可以通过以下方式成功构建 ios: ionic build ios and ionic build ios --prod 但当我这样做时,它一直失败
我是一位经验丰富的 .NET/C# 开发人员,但对这里的几乎所有技术/库(包括 SQL/DB 工作)都是新手。 我正在开发一个具有 Azure/Entity Framework .NET 后端和可移植
我正在使用 VS 2008。我可以使用 IDE 成功编译我的解决方案。但是,当我尝试使用 devenv.com 构建它时,它失败并提示“错误:找不到项目输出组'(无法确定名称)的输出”。该组、其配置或
版本: ember.js 2.7,ember-data 2.7 ember-cli 2.9.1//同样适用于 ember-cli 2.7 node 6.9.1, npm 3.10.9//也适用于 no
我第一次修补 AzureDevops,设置一些 CI 任务。 我有一个公共(public)存储库(开源)和一个包含 3 个 F# 项目的解决方案(.sln)。该解决方案在 Windows/Mac/Li
目前 5.1.5 版本或 STLPort CVS 存储库似乎仍不支持 VS2008。如果有人已经完成了这项工作,那么如果可能的话,分享会很有用:) 同样,了解 VS2005 或 2008 x64 构建
我有一个 Python 2.7 项目,到目前为止一直使用 gfortran 和 MinGW 来构建扩展。我使用 MinGW,因为它似乎支持 Fortran 代码中的写入语句和可分配数组,而 MSVC
关闭。这个问题是off-topic .它目前不接受答案。 想改进这个问题? Update the question所以它是on-topic对于堆栈溢出。 9年前关闭。 Improve this que
我想知道为什么在 Zimbra Wiki 中只列出了构建过程的特定平台。这意味着不可能在其他 Linux 发行版上构建 Zimbra? Zimbra 社区选择一个特殊的 Linux 发行版来构建 Zi
我将在 Swift 中构建一个 CLI 工具。我用这个命令创建了项目 swift package init --type executable当我构建我的项目并解析 时读取别名 Xcode 中的参数并
我想为添加到 docker 镜像的文件设置文件权限。我有这个简单的 Dockerfile: FROM ubuntu:utopic WORKDIR /app RUN groupadd -g 1000 b
当我使用 clBuildProgram在我的 OpenCl 代码中,它失败并显示错误代码 -11,没有任何日志信息。 这是我的代码的样子: ret = clBuildProgram(program
我有一个底部导航栏,它有一个列表页面,该页面使用状态块。 class _MainPageState extends State { int _index = 0; @override Wi
我在本地计算机上使用Jenkins(Jenkins URL未通过Internet公开,但该计算机上已启用Internet。) 我进行了以下配置更改: 在Jenkins工具上安装了Git和Github插
我是一名优秀的程序员,十分优秀!