Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/70.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 空值时的查询性能_Sql_Sql Server_Database_Performance - Fatal编程技术网

Sql 空值时的查询性能

Sql 空值时的查询性能,sql,sql-server,database,performance,Sql,Sql Server,Database,Performance,我想知道空值如何影响SQLServer2005中的查询性能 我有一张类似的表格(简化): 我正在对它进行如下查询: SELECT * FROM MyTable WHERE QuickPickOrder IS NOT NULL ORDER BY QuickPickOrder 因此QuickPickOrder基本上是一个列,用于从较大的列表中挑出一些常用的项。它还提供了它们向用户显示的顺序。空值表示它不显示在快速拾取列表中 我一直被告知,数据库中的空值在某种程度上是有害的,至少从

我想知道空值如何影响SQLServer2005中的查询性能

我有一张类似的表格(简化):

我正在对它进行如下查询:

SELECT   *
FROM     MyTable
WHERE    QuickPickOrder IS NOT NULL
ORDER BY QuickPickOrder
因此QuickPickOrder基本上是一个列,用于从较大的列表中挑出一些常用的项。它还提供了它们向用户显示的顺序。空值表示它不显示在快速拾取列表中

我一直被告知,数据库中的空值在某种程度上是有害的,至少从规范化的角度来看是如此,但在WHERE约束中过滤掉不需要的行是一种可以接受的方式吗

使用特定的数值(如-1或0)来表示不需要的项目是否更好?还有其他选择吗

编辑:
该示例无法准确表示实值与空值的比率。更好的示例可能会显示每个非NULL至少10个NULL。表格大小可能为100到200行。这是一个参考表,所以很少有更新。

NULL
在我看来,这很好。性能可能与使用非空列和常量值时基本相同,或者甚至更好地过滤掉所有
null
s。

它们不会对数据库造成负面性能影响。请记住,NULL更像是一种状态而不是一个值。检查NOTNULL与将该值设置为-1没有区别,除了-1可能会破坏您的数据完整性,依我看。

SQL Server
索引
NULL
值,因此这很可能只是在
QuickPickOrder
上的索引上使用
索引搜索
,用于筛选和排序。

另一种方法是使用外键将QuickPickOrder规范化为一个表,然后执行内部联接以筛选空值(或使用where子句进行左联接以筛选非空值)。

空值对我来说也很好。SQL Server有多种索引可供选择。我忘了是哪一个这样做了,但有些只是在给定范围内的索引值。如果测试列上有这种索引,空值记录将不在索引中,索引扫描将很快。

另一种选择是两个表:

MyTable:

ID | ImportantData
------------------
1  | 'Some Text'
2  | 'Other Text'
3  | 'abcdefg'
4  | 'whatever'
5  | 'it is'
6  | 'technically'
7  | 'a varchar'
8  | 'of course'
9  | 'but that'
10 | 'is not'
11 | 'important'

QuickPicks:

MyTableID   | QuickPickOrder
--------------------------
2           | 3
4           | 4
5           | 2
8           | 1
11          | 5

SELECT   MyTable.*
FROM     MyTable JOIN QuickPicks ON QuickPickOrder.MyTableID = MyTable.ID
ORDER BY QuickPickOrder
这将允许在不锁定MyTable中的任何内容或记录该表的整行事务的情况下更新QuickPickOrder。因此,根据MyTable的大小以及更新QuickPickOrder的频率,可能存在可伸缩性优势


另外,拥有一个单独的表将允许您在QuickPickOrder上添加一个唯一的索引,以确保没有重复,并且可以更容易地在以后进行缩放,以允许不同类型的快速选取,使它们特定于特定的上下文或用户等。

在一个列中有大量空值,该列上有索引(或从索引开始)通常对这种查询是有益的

索引中不输入NULL值,这意味着插入/更新其中包含NULL的行不会受到必须更新另一个辅助索引的性能影响。比如说,如果该列中只有0.001%的行具有非null值,那么IS NOT null查询将变得非常有效,因为它只扫描相对较小的索引


当然,所有这些都是相对的,如果您的表很小,则不会产生明显的差异。

在数据库中使用空值可能会影响SQL Server的性能。这有几个原因

首先,出现在固定长度列(CHAR)中的空值占据整个列的大小。因此,如果列的宽度为25个字符,并且其中存储了空值,那么SQL Server必须存储25个字符来表示空值。增加的空间增加了数据库的大小,这反过来意味着查找所需数据需要更多的I/O开销。当然,解决这个问题的一种方法是使用可变长度字段。将空值添加到可变长度列时,空间不会像固定长度列那样被不必要地浪费

其次,在WHERE子句中使用IS NULL子句意味着索引不能用于查询,将执行表扫描。这会大大降低性能

第三个,使用空值可能会导致复杂的Transact-SQL代码,这可能意味着代码无法高效运行或存在缺陷

理想情况下,SQL Server数据库中应该避免空值

在数据库中使用与此类似的编码方案,而不是使用空值:

  • NA:不适用
  • 尼恩:还不知道
  • 谭:真的不知道

这种方案提供了使用null的好处,但没有缺点。

如果表的列为50%null(类似于给定的示例数据),我认为它可能倾向于使用索引scan@KM:为什么在这里进行索引扫描?它可能会执行表扫描/聚集索引扫描以避免RID查找/键查找,但我们这里有一个范围条件,因此索引查找总是优于此条件。它不会忽略索引和扫描,因为大多数值都是相同的(null)?@KM:它可以这样做,但它不会是索引扫描,而是表扫描或聚集索引扫描(与群集表的表扫描相同).Index Scan意味着在QuickPickOrder上遍历整个索引,过滤掉错误的值,然后使用键查找/RID查找与表连接,以获取SELECT子句请求的*值。Index Seek执行相同的操作,但从第一个非空值开始,因此空值只是剩余值。筛选的索引设计指南显示,您可以如果您有一个使用筛选索引的列的值大部分为空,则索引将具有更好的性能。
MyTable:

ID | ImportantData
------------------
1  | 'Some Text'
2  | 'Other Text'
3  | 'abcdefg'
4  | 'whatever'
5  | 'it is'
6  | 'technically'
7  | 'a varchar'
8  | 'of course'
9  | 'but that'
10 | 'is not'
11 | 'important'

QuickPicks:

MyTableID   | QuickPickOrder
--------------------------
2           | 3
4           | 4
5           | 2
8           | 1
11          | 5

SELECT   MyTable.*
FROM     MyTable JOIN QuickPicks ON QuickPickOrder.MyTableID = MyTable.ID
ORDER BY QuickPickOrder