【发布时间】:2021-02-16 22:59:18
【问题描述】:
我创建了一个包含以下列的表格。所有列都是唯一键(列)我的表中没有主键。
表Product:
Bat_Key,
product_no,
value,
pgm_name,
status,
industry,
created_by,
created_date
我已经更改了我的表格以添加约束
ALTER TABLE [dbo].[Product]
ADD CONSTRAINT [PRODUCT_PK]
PRIMARY KEY NONCLUSTERED ([Bat_Key] ASC, [product_no] ASC,
[value] ASC, [pgm_name] ASC, )
WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF) ON [PRIMARY]
GO
如果我创建如下索引:
CREATE NONCLUSTERED INDEX [PRODUCT_BKEY_PNO_IDX]
ON [dbo].[PRODUCT] ([Bat_Key] ASC, [product_no] ASC, [value], [pgm_name])
INCLUDE ([status], [industry])
WITH (STATISTICS_NORECOMPUTE = OFF, DROP_EXISTING = OFF, ONLINE = OFF) ON [PRIMARY]
GO
这种设计是否适合以下选择查询:
select *
from Product
where Bat_Key = ? and product_no=?
order by product_no, pgm_name;
select *
from Product
where Bat_Key = ? and product_no=? and pgm_name = ? and value = ?
select *
from Product
where Bat_Key = ? and product_no=?
delete from Product
where Bat_Key = ? and product_no=?
或者我应该根据我的where 子句创建不同的索引?
【问题讨论】:
-
如果我没记错的话,主键会自动创建一个聚集索引。可能没有必要在相同字段上创建非聚集索引。
-
主键约束总是由唯一索引支持,无论是否聚集。
PRODUCT_BKEY_PNO_IDX索引将是多余的。 (它不能在您的查询中使用,因为它没有覆盖;created_*字段仍然需要在任何SELECT *中查找。)您通常需要一个聚集索引,即使它只在一个IDENTITY字段上你不会以其他方式使用。这样的字段也可以作为在数据库中使用的更实用的代理键,而不是包括文本在内的四个字段。 -
您使用的是哪个 dbms? (这是一个产品特定的问题。)
-
@jarlh - 我正在使用 Azure SQL 数据库
-
没有绝对的性能。想知道?您测试您的查询并检查执行计划。没有什么是免费的。维护额外的索引是有成本的。只关注几个 SELECT 语句可能会给您带来误导性的方向。更重要的是 - 您应该仔细考虑堆是否适合此表及其用途。
标签: sql-server indexing ddl non-clustered-index