使用索引加速SQL查询

17

我有一个名为Products的表。

这个表包含超过300万条记录。每天大约会有5000个新条目添加,只会在晚上的2分钟内发生。

但是这个表每晚都会被查询超过20,000次,使用的是下面这个查询语句。

SELECT Price 
FROM Products 
WHERE Code = @code 
  AND Company = @company 
  AND CreatedDate = @createdDate

表结构:

Code          nvarchar(50)
Company       nvarchar(10)
CreatedDate   datetime

我发现这个查询需要大约一秒钟的时间才能从Products表返回结果。

该表中没有productId列,因为它不是必需的。因此该表中没有主键。

我希望能够改进此查询以更快地返回结果。

我以前从未使用过索引。在这个表上使用索引的最佳方法是什么?

如果我提供主键,您认为它会加速查询结果吗?请记住,我仍然需要通过提供3个参数来查询该表。

WHERE Code = @code 
  AND Company = @company 
  AND CreatedDate = @createdDate. 

这是必需的。

正如我所提到的,每天晚上表格会在2分钟内获得新条目。这会影响索引吗?

如果我使用索引,哪一列最好使用,我应该使用聚集索引还是非聚集索引?


在SSMS中显示查询的预估执行计划时,您是否会得到索引建议? - hatchet - done with SOverflow
1
每个表都应该有一个主键,即使它只是一个代理键。因此,该表中没有主键。@wewesthemenace的索引看起来很合适。 - Mitch Wheat
查询通过控制台应用程序运行。从未在SSMS中使用执行计划@hatchet。 - akd
谢谢您的建议,但能否再解释一下您的问题。也许您可以将问题作为答案回复。wewesthemenace - akd
1
每个表都应该有一个聚集索引,或者至少在表被更新/删除的情况下需要一个,因为这可能会导致表严重碎片化和浪费空间。 - James Z
显示剩余5条评论
1个回答

17

根据表中的其他字段和运行在该表上的其他查询来确定最佳操作。没有更多详细信息的情况下,在(code, company, createddate) 上建立一个非聚集索引,并包含"price"列,肯定会提高性能。

CREATE NONCLUSTERED INDEX IX_code_company_createddate
ON Products(code, company, createddate)
INCLUDE (price);

这是因为如果您有该索引,那么在运行查询时,SQL将根本不访问实际表格,因为它可以在索引中查找给定“code,company,createddate”的所有行,并且当使用定义键的字段进行访问时,索引允许精确快速访问,而且它还会为每行提供“price”值。

关于插入操作,对于添加的每一行,SQL Server也必须将其添加到索引中,因此插入性能将受到影响。我认为你应该期望选择性能的增益大于对插入的影响,但你应该进行测试。

此外,您将使用更多的空间,因为索引将为每行存储所有这些字段,除了原始表格使用的空间。

正如其他评论中指出的那样,为您的表格添加一个主键(即使这意味着添加一个您实际上不需要的ProductId列)也可能是一个好主意。


1
如果是我,我会反转顺序:CreatedDate,Company,Code - Felix Pamittan
6
难以置信,这个过程像硝基一样加速了。非常感谢。是的,就像你所提到的,在创建索引之前和之后插入操作大约需要2分钟,但从2小时缩短到了5分钟的查询操作,真的难以置信 :) - akd
1
@akdurmus 现在你看到索引的魔力了吧 ;) 当然:如果你有300万条记录而没有索引,那么数据库需要扫描整个表;这意味着3百万次访问,平均1.5百万次!但是如果你有一个索引,那么数据库只需要1到3(!)次磁盘访问!索引的工作原理类似于书中的索引:你查找第一个字母,然后是第二个字母,然后你就到了目标位置。 - SQL Police
添加这个索引会加快价格更新还是减慢它?谢谢。 - from56

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接