我想知道NULL值如何影响SQL Server 2005中的查询性能。
我有一张类似于此的表(简化):
ID | ImportantData | QuickPickOrder
--------------------------
1 | 'Some Text' | NULL
2 | 'Other Text' | 3
3 | 'abcdefg' | NULL
4 | 'whatever' | 4
5 | 'it is' | 2
6 | 'technically' | NULL
7 | 'a varchar' | NULL
8 | 'of course' | 1
9 | 'but that' | NULL
10 | 'is not' | NULL
11 | 'important' | 5
我正在对此进行查询:
SELECT *
FROM MyTable
WHERE QuickPickOrder IS NOT NULL
ORDER BY QuickPickOrder
因此,QuickPickOrder基本上是一个用于从较大列表中挑选出一些常用项目的列。它还提供了它们对用户显示的顺序。 NULL值表示它不会显示在快速选择列表中。
我总是被告知数据库中的NULL值在某种程度上是邪恶的,至少从标准化的角度来看,但是它是否可以在WHERE约束中过滤掉不需要的行?
使用特定的数字值(如-1或0)来表示不需要的项目会更好吗?还有其他选择吗?
修改 该示例并不准确地表示实际值与NULL的比率。更好的示例可能会为每个非NULL显示至少10个NULL。表大小可能是100到200行。它是一个参考表,所以更新很少见。
答案 0 :(得分:5)
SQL Server
索引NULL
值,因此这很可能仅使用Index Seek
而不是QuickPickOrder
上的索引,用于过滤和排序。
答案 1 :(得分:3)
另一种选择是两个表:
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
这样可以更新QuickPickOrder,而无需锁定MyTable中的任何内容或记录该表的完整行事务。因此,根据MyTable的大小以及更新QuickPickOrder的频率,可能会有可扩展性优势。
此外,拥有一个单独的表将允许您在QuickPickOrder上添加唯一索引以确保不会重复,并且可以在以后更容易扩展以允许不同类型的QuickPicks,使它们特定于某些上下文或用户等。< / p>
答案 2 :(得分:2)
他们没有对数据库造成负面影响。请记住,NULL更多的是状态而不是值。检查NOT NULL与将该值设置为-1没有区别,除了-1可能会破坏您的数据完整性,imo。
答案 3 :(得分:1)
NULL
对我来说很好。性能可能与非空列和常量值基本相同,或者甚至可能更好地过滤掉所有NULL
。
答案 4 :(得分:1)
另一种方法是将QuickPickOrder规范化为具有外键的表,然后执行内部联接以过滤掉空值(或使用where子句的左连接来过滤掉非空值)。
答案 5 :(得分:1)
在数据库中使用NULLS可能会影响SQL Server的性能。这有几个原因。
首先,出现在固定长度列(CHAR)中的NULLS占用了列的整个大小。因此,如果您有一个25个字符宽的列,并且其中存储了NULL,则SQL Server必须存储25个字符来表示NULL值。这个增加的空间增加了数据库的大小,这反过来意味着它需要更多的I / O开销来查找您正在寻找的数据。当然,解决此问题的一种方法是使用可变长度字段。当NULL被添加到可变长度列时,空间不会被浪费,因为它具有固定长度的列。
第二,在WHERE子句中使用IS NULL子句意味着索引不能用于查询,并且将执行表扫描。这可能会大大降低性能。
第三次,使用NULLS会导致错综复杂的Transact-SQL代码,这可能意味着代码无法有效运行或有错误。
理想情况下,应在SQL Server数据库中避免使用NULL。
不使用NULL,而是在数据库中使用与此类似的编码方案:
这样的方案提供了使用NULL的好处,但没有缺点。
答案 6 :(得分:0)
NULL对我来说也很好看。 SQL Server有多种索引可供选择。我忘记了哪些人这样做,但有些只是给定范围内的索引值。如果您正在测试的列上有这种索引,则NULL值记录将不在索引中,并且索引扫描会很快。
答案 7 :(得分:0)
在列中有很多NULL,其上有一个索引(或从它开始)通常有利于这种查询。
未在索引中输入NULL值,这意味着在其中插入/更新具有NULL的行不会影响必须更新另一个二级索引的性能。例如,如果只有0.001%的行在该列中具有非空值,则IS NOT NULL查询变得非常有效,因为它只扫描相对较小的索引。
当然所有这些都是相对的,如果你的桌子很小,它没有任何明显的区别。