Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/75.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 使用VARCHAR2字段上的索引,其中VARCHAR2是日期_Sql_Oracle - Fatal编程技术网

Sql 使用VARCHAR2字段上的索引,其中VARCHAR2是日期

Sql 使用VARCHAR2字段上的索引,其中VARCHAR2是日期,sql,oracle,Sql,Oracle,我有一个Oracle表,该表有一个LETTER_SENT date字段。发送的字母_是一个varchar2字段,是一个文本字符串yyyymmdd(因此20140708表示该字母是在2014年7月8日发送的)。注意:这不是我的表,我只能在上面选择授权,所以我不能强制它为yyyymmdd日期 通常,我需要查找在一定日期范围内发送的信件。通常,我会在('开始日期',…,'结束日期')中的何处执行。根据我对SQL的理解,这样做不会以任何方式修补字段,而不会影响索引的使用(而转换为日期或数字,然后进行比较

我有一个Oracle表,该表有一个LETTER_SENT date字段。发送的字母_是一个varchar2字段,是一个文本字符串yyyymmdd(因此20140708表示该字母是在2014年7月8日发送的)。注意:这不是我的表,我只能在上面选择授权,所以我不能强制它为yyyymmdd日期

通常,我需要查找在一定日期范围内发送的信件。通常,我会在('开始日期',…,'结束日期')中的何处执行。根据我对SQL的理解,这样做不会以任何方式修补字段,而不会影响索引的使用(而转换为日期或数字,然后进行比较会影响索引)

就性能而言,这很好。然而,有时我的约会范围很大,在……或……中有一个巨大的范围。。。或者在WHERE语句的从句中是丑陋的罪恶


当日期是索引varchar2时,where子句(date\u begin和date\u end之间的日期)中是否还有另一种语法上更漂亮但仍然有效的方法进行日期比较

正确的方法是存储使用日期数据类型而不是VARCHAR2()发送的信函。在语法、索引的使用、结果的正确性、优化器统计信息以及最终的性能方面,您的情况会好得多

正确的方法是存储使用日期数据类型而不是VARCHAR2()发送的信函。在语法、索引的使用、结果的正确性、优化器统计信息以及最终的性能方面,您的情况会好得多

由于您在varchar2字段上有一个索引,我相信您将能够使用如下查询:

select * from tablename
where letter_sent >= '20160101' and letter_sent <= '20160430'
从tablename中选择*

如果letter_sent>='20160101'和letter_sent,因为您在varchar2字段上有索引,我相信您将能够使用如下查询:

select * from tablename
where letter_sent >= '20160101' and letter_sent <= '20160430'
从tablename中选择*


你有没有试过写这封信?“'20160101'和@zedfoxus”这封信?“'20160101'和@zedfoxus”这封信更好?我真不敢相信我竟然忘了这封信!请将此作为答案发布,这样我就可以投票并接受它,拍我的头说我忘了这个。Tom Kyte做了一个非常有说服力的会议演示(我曾在OTN上的一个帖子中看到一个链接)-他给出了具体的例子,说明了对于完全相同的数据,
VARCHAR2
列上的索引与适当的
DATE
列上的索引相比,本应编码日期的索引的性能非常差(该列的不同数据类型除外)。不要将
VARCHAR2
用于日期;这是100多个很好的理由之一。这里有一个非常简单的例子。想象有两次约会。优化器将尝试生成行数的基数估计。当存储为VARCHAR2时。20170101-20161230是8871。实际上,这个值应该是1。@Joe我已经添加了我的答案,还包括了其他评论者提供的相同建议——使用日期字段而不是varchar2以获得长期效果。你是否尝试过使用
letter_sent>='20160101'和letter_sent@zedfoxus这两种方法效果更好?我简直不敢相信忘了这是有用的!请将此作为答案发布,这样我就可以投票并接受它,拍我的头说我忘了这个。Tom Kyte做了一个非常有说服力的会议演示(我曾在OTN上的一个帖子中看到一个链接)-他给出了具体的例子,说明了对于完全相同的数据,
VARCHAR2
列上的索引与适当的
DATE
列上的索引相比,本应编码日期的索引的性能非常差(该列的不同数据类型除外)。不要将
VARCHAR2
用于日期;这是100多个很好的理由之一。这里有一个非常简单的例子。想象有两次约会。优化器将尝试生成行数的基数估计。当存储为VARCHAR2时。20170101-20161230是8871。实际上,该值应该是1。@Joe我已经添加了我的答案,还包括了其他评论者提供的相同建议-使用日期字段而不是varchar2以获得长期效果。相信我,我知道-这不是我的表:/。我不知道为什么表创建者选择这样做。我将编辑原稿以反映这一点。不管怎样,向上投票,这样以后来的人都会知道如何避免:)@Joe。我强烈建议您回到表创建者那里,修复这个问题。我已经记不清升级的次数了。此外,由于类型转换,您将隐式禁用Oracle优化。如果创作者拒绝,任何人都可以;去找他们的经理!!我会告诉他们,但我不希望有什么变化。大公司行动缓慢,什么都没有改变。相信我,我知道-这不是我的桌子:/。我不知道为什么表创建者选择这样做。我将编辑原稿以反映这一点。不管怎样,向上投票,这样以后来的人都会知道如何避免:)@Joe。我强烈建议您回到表创建者那里,修复这个问题。我已经记不清升级的次数了。此外,由于类型转换,您将隐式禁用Oracle优化。如果创作者拒绝,任何人都可以;去找他们的经理!!我会告诉他们,但我不希望有什么变化。大公司行动缓慢,什么也没有改变。@Joe-还有无数的其他好处。想象一下,如果日期为
varchar2
数据类型,那么确定后续信函是否在最初的10个工作日内发送是多么容易!很高兴知道为什么答案会被否决。我想知道这个答案是否可以改进。因为鼓励“不良行为”而被否决。客户应使用正确的数据类型。见下面的答案。另请参阅我上面的评论/示例,了解为什么这不好。@BobC明白了。我很感激。我的意图是提供信息