首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在数据库搜索中,空值如何影响性能?

在数据库搜索中,空值如何影响性能?
EN

Stack Overflow用户
提问于 2009-06-19 10:05:15
回答 8查看 59.9K关注 0票数 48

在我们的产品中,我们有一个通用的搜索引擎,并试图优化搜索性能。查询中使用的许多表都允许空值。我们是否应该重新设计我们的表,以禁止空值用于优化?

我们的产品既可以在Oracle上运行,也可以在MS SQL Server上运行。

EN

回答 8

Stack Overflow用户

回答已采纳

发布于 2009-06-19 10:24:46

Oracle中,NULL值没有索引,即这个查询:

代码语言:javascript
运行
复制
SELECT  *
FROM    table
WHERE   column IS NULL

将始终使用全表扫描,因为索引不会覆盖所需的值。

更重要的是,这个查询:

代码语言:javascript
运行
复制
SELECT  column
FROM    table
ORDER BY
        column

出于同样的原因,还将使用全表扫描和排序。

如果您的值本质上不允许NULL,则将该列标记为NOT NULL

票数 42
EN

Stack Overflow用户

发布于 2009-06-19 10:15:54

简短的回答:是的,有条件的!

空值和性能的主要问题是与正向查找有关。

如果您在表中插入一行,并使用空值,那么它将被放在它所属的自然页中。任何查找该记录的查询都会在适当的位置找到它。到目前为止很简单……

...but假设页面已填满,现在该行被夹在其他行中。仍然进展顺利..。

...until行被更新,并且空值现在包含一些内容。行的大小已经超出了它可以使用的空间,所以DB引擎必须对其采取一些措施。

服务器执行的最快的操作是将行从该页移到另一页,并用前向指针替换该行的条目。不幸的是,这需要在执行查询时进行额外的查找:一个查找行的自然位置,另一个查找行的当前位置。

所以,对你的问题的简短回答是肯定的,使这些字段不可为空将有助于提高搜索性能。如果经常发生您搜索的记录中的空字段被更新为非空字段的情况,这一点尤其正确。

当然,还有其他与大型数据集相关的损失(特别是I/O,尽管索引深度很小),而且在概念上需要空值的字段中不允许出现空值,这会导致应用程序出现问题,但嘿,这是另一个问题:)

票数 16
EN

Stack Overflow用户

发布于 2009-06-20 09:07:39

这是一个额外的答案,以引起人们对David Aldridge对Quassnoi接受的答案的评论的额外关注。

声明:

此查询:

SELECT * FROM表WHERE column为空

将始终使用全表扫描

不是真的。以下是使用带有文字值的索引的计数器示例:

代码语言:javascript
运行
复制
SQL> create table mytable (mycolumn)
  2  as
  3   select nullif(level,10000)
  4     from dual
  5  connect by level <= 10000
  6  /

Table created.

SQL> create index i1 on mytable(mycolumn,1)
  2  /

Index created.

SQL> exec dbms_stats.gather_table_stats(user,'mytable',cascade=>true)

PL/SQL procedure successfully completed.

SQL> set serveroutput off
SQL> select /*+ gather_plan_statistics */ *
  2    from mytable
  3   where mycolumn is null
  4  /

  MYCOLUMN
----------


1 row selected.

SQL> select * from table(dbms_xplan.display_cursor(null,null,'allstats last'))
  2  /

PLAN_TABLE_OUTPUT
-----------------------------------------------------------------------------------------
SQL_ID  daxdqjwaww1gr, child number 0
-------------------------------------
select /*+ gather_plan_statistics */ *   from mytable  where mycolumn
is null

Plan hash value: 1816312439

-----------------------------------------------------------------------------------
| Id  | Operation        | Name | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
-----------------------------------------------------------------------------------
|   0 | SELECT STATEMENT |      |      1 |        |      1 |00:00:00.01 |       2 |
|*  1 |  INDEX RANGE SCAN| I1   |      1 |      1 |      1 |00:00:00.01 |       2 |
-----------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - access("MYCOLUMN" IS NULL)


19 rows selected.

正如您所看到的,索引正在使用中。

问候你,罗伯。

票数 14
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1017239

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档