2013-04-08 56 views
3

我有一个来自NET的面试问题,但没有找到正确的解决方案,任何人都可以告诉 我这个查询有什么问题?关于索引的SQL服务器访问查询?

鉴于此表结构和索引,后续查询有什么问题?

CREATE TABLE dbo.IndexQ (
ID int IDENTITY(1, 1) NOT NULL, 
TestBit bit NOT NULL 
) 
GO 

CREATE NONCLUSTERED INEX IX_IndexQ_TestBit ON dbo.IndexQ (TestBit) 
GO 

* Insert some rows where some bits are 0 and some are 1... 

SELECT * 
FROM dbo.IndexQ 
WHERE TestBit = 1 
* What's the problem with this query? 
+1

在附注中,它对低基数列具有'index'效率不高 – praveen 2013-04-08 09:20:04

回答

3

我想对位字段的非聚集索引的问题。如果你有一张大桌子,你不应该在位字段上建立索引,因为那么它有更多的记录,索引会起作用的效率会降低,但是会使用更多的日期。

参见https://dba.stackexchange.com/questions/12888/should-i-index-a-bit-field-in-sql-server

+0

如果可能,您可以深入解释。 – Luv 2013-04-08 09:38:12

+1

@Luv好吧,当你有不同的值时,索引本身是有用的(在大多数情况下)。它可以避免你进行全表扫描,用索引表扫描取代它,这是更快的,因为这些表几次更小。它们的大小取决于列值和它们的变化。在位域的情况下,SQL将只有两个值,除了位索引表以外,进行表搜索的代价几乎相同。另一方面,这个索引将存储非公平的指针,这将花费你一些空间 – Alex 2013-04-08 09:58:15

+0

+1对于**解释** – Luv 2013-04-08 10:04:53

1

1),用于创建索引的普遍的做法是,第一索引列应具有较高的选择性/低密度柱(密度示出了唯一值多少是一列内或一组列的)。较低的密度(意味着许多独特的价值)更好,因为这比Index Scan更利于Index Seek。在这种情况下,BIT列中的索引意味着更高的密度,这有利于Index Scan

2)但是,SELECT *强制服务器返回所有列,而不仅仅是从TestBit返回的值(TestBit)。这意味着,对于此SELECT查询,索引是不覆盖的(不包括此查询所需的所有列)。 3)更高的密度(1)加上非覆盖索引(2)意味着该索引的"tipping point"很可能会强制服务器不使用此索引,而是选择(非常可能)表扫描。

这表示该索引无用。

+0

注意:这意味着,这个索引对**这个查询**没有用。 – 2013-04-08 11:43:04