如何为具有空值的日期列建立索引?
当某些行具有空值时,我应该如何索引日期列? 我们必须选择日期范围之间的行和具有空日期的行。
我们使用 Oracle 9.2 及更高版本。
我找到的选项
- 在日期列上使用位图索引
- 在日期列上使用索引,在状态字段上使用索引,当日期为空时,状态字段的值为 1
- 在日期列上使用索引,并在其他授予的非空列上使用索引
我的想法选项有:
到 1:表必须有许多不同的值才能使用位图索引
到 2:我必须仅为此目的添加一个字段,并在我想要检索空日期行时更改查询
3:锁定很难将字段添加到实际上不需要的索引
这种情况的最佳实践是什么? 提前致谢
我读过的一些信息:
Oracle Date Index
Oracle何时索引空列值?
编辑
我们的表有300,000条记录。每天插入和删除1,000到10,000条记录。 280,000 条记录的 Delivered_at 日期为空。它是一种拾取缓冲区。
我们的结构(翻译成英文)是:
create table orders
(
orderid VARCHAR2(6) not null,
customerid VARCHAR2(6) not null,
compartment VARCHAR2(8),
externalstorage NUMBER(1) default 0 not null,
created_at DATE not null,
last_update DATE not null,
latest_delivery DATE not null,
delivered_at DATE,
delivery_group VARCHAR2(9),
fast_order NUMBER(1) default 0 not null,
order_type NUMBER(1) default 0 not null,
produkt_group VARCHAR2(30)
)
How should I index a date column when some rows has null values?
We have to select rows between a date range and rows with null dates.
We use Oracle 9.2 and higher.
Options I found
- Using a bitmap index on the date column
- Using an index on date column and an index on a state field which value is 1 when the date is null
- Using an index on date column and an other granted not null column
My thoughts to the options are:
to 1: the table have to many different values to use an bitmap index
to 2: I have to add an field only for this purpose and to change the query when I want to retrieve the null date rows
to 3: locks tricky to add an field to an index which is not really needed
What is the best practice for this case?
Thanks in advance
Some infos I have read:
Oracle Date Index
When does Oracle index null column values?
Edit
Our table has 300,000 records. 1,000 to 10,000 records are inserted and delete every day. 280,000 records have a null delivered_at date. It is a kind of picking buffer.
Our structure (translated to english) is:
create table orders
(
orderid VARCHAR2(6) not null,
customerid VARCHAR2(6) not null,
compartment VARCHAR2(8),
externalstorage NUMBER(1) default 0 not null,
created_at DATE not null,
last_update DATE not null,
latest_delivery DATE not null,
delivered_at DATE,
delivery_group VARCHAR2(9),
fast_order NUMBER(1) default 0 not null,
order_type NUMBER(1) default 0 not null,
produkt_group VARCHAR2(30)
)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
除了托尼的出色建议之外,还有一个选项可以为您的列建立索引,这样您就无需调整查询。诀窍是仅向索引添加一个常量值。
演示:
创建一个包含 10,000 行的表,其中只有 6 行的 a_date 列包含 NULL 值。
首先,我将展示如果您只是在 a_date 列上创建索引,那么当您使用谓词“where a_date is null”时,不会使用该索引:
720 一致获取和全表扫描。
现在更改索引以包含常量 1,并重复测试:
6 次一致获取和索引范围扫描。
问候,
抢。
In addition to Tony's excellent advice, there is also an option to index your column in such a way that you don't need to adjust your queries. The trick is to add a constant value to just your index.
A demonstration:
Create a table with 10,000 rows out of which only 6 contain a NULL value for the a_date column.
First I'll show that if you just create an index on the a_date column, the index is not used when you use the predicate "where a_date is null":
720 consistent gets and a full table scan.
Now change the index to include the constant 1, and repeat the test:
6 consistent gets and an index range scan.
Regards,
Rob.
换句话说,几乎整个表都满足搜索 DELIVERED_AT 为空的查询。索引完全不适合该搜索。全表扫描是最好的方法。
如果您有企业版许可证并且有 CPU为了节省时间,使用并行查询会减少花费的时间。
In other words almost the entire table satisfies a query which searches on where DELIVERED_AT is null. An index is completely inappropriate for that search. A full table scan is much the best approach.
If you have an Enterprise Edition license and you have the CPUs to spare, using a parallel query would reduce the elapsed time.
你的意思是你的查询会是这样的吗?
只有当空值在表中相对较少时才值得对空值建立索引 - 否则全表扫描可能是查找它们的最有效方法。假设值得对它们建立索引,您可以创建一个基于函数的索引,如下所示:
然后将查询更改为:
您可以将案例包装在函数中以使其更平滑:
我确保当日期不为空时函数返回 NULL,所以仅空日期存储在索引中。我还必须将该函数声明为 DETERMINISTIC。 (我将其更改为返回“Y”而不是 1,仅仅是因为对我来说名称“isnull”表明它应该这样做;请随意忽略我的偏好!)
Do you mean that your queries will be like this?
It would only be worth indexing the nulls if they were relatively few in the table - otherwise a full table scan may be the most efficient way to find them. Assuming it is worth indexing them you could create a function-based index like this:
Then change your query to:
You could wrap the case in a function to make it slicker:
I made sure the function returns NULL when the date is not null so that only the null dates are stored in the index. Also I had to declare the function as DETERMINISTIC. (I changed it to return 'Y' instead of 1 merely because to me the name "isnull" suggests it should; feel free to ignore my preference!)
避免表查找并创建索引,如下所示:
Avoid the table lookup and create the index like this :