我有一个已经按“datetime”列排序的表格。因为插入时我会存储UTC日期,所以它是有序的。这是一张人口稠密的桌子。所以我试图提高查询性能,如果可能的话。
当我使用WHERE columnDateTime > dateToSearch
时,返回行需要很长时间。由于我的表已按columnDateTime
排序,我该怎么做才能提高查询性能。例如,当一个表按cod
排序并且您尝试搜索cod > 40
时,T-SQL优化会在找到cod = 41时停止搜索并返回表的其余部分,因为它知道该表是由该索引排序的。这是一种可以告诉T-SQL我的表已经由columnDateTime
订购的方法吗?
答案 0 :(得分:3)
按顺序插入数据并不意味着它按顺序保存。没有太过技术性和更快的性能:
在该列上创建CLUSTERED INDEX
。这要求您表上没有其他聚簇索引,并且它没有PRIMARY KEY
(或者它具有NONCLUSTERED
,这不是默认值)。使用聚簇索引时,引擎将在使用> datetimeValue
进行过滤时执行索引扫描(而不是全表扫描),并且不需要访问数据的附加页面,因为聚簇索引会离开是数据。
在该列上创建NONCLUSTERED INDEX
。对此子句没有限制(至少在这种情况下),但是对于每个与过滤日期的匹配,引擎将需要访问具有请求列的另一个页面,除非您在创建索引时INCLUDE
。请记住,包含的列会增加索引的大小,并且需要额外的维护任务,例如,当修改包含的列时。
除此之外,您应该检查您的查询计划;如果你有连接,函数调用或附加条件,SQL引擎可能不会使用索引,即使它们存在。有很多事情可能导致查询运行缓慢,您必须发布完整的查询执行计划(开始)以检查详细信息。
您可以使用此查询来检查您的表是否已有索引:
DECLARE @table_name VARCHAR(200) = 'YourTableName'
SELECT
SchemaName = SCHEMA_NAME(t.schema_id),
TableName = t.name,
IndexName = ind.name,
IndexType = CASE ind.index_id WHEN 0 THEN 'Heap' WHEN 1 THEN 'Clustered' ELSE 'Nonclustered' END,
Disabled = ind.is_disabled,
ColumnOrder = ic.index_column_id,
ColumnName = col.name,
ColumnType = y.name,
ColumnLength = y.max_length,
ColumnIncluded = ic.is_included_column
FROM
sys.indexes ind
INNER JOIN sys.index_columns ic ON ind.object_id = ic.object_id and ind.index_id = ic.index_id
INNER JOIN sys.columns col ON ic.object_id = col.object_id and ic.column_id = col.column_id
INNER JOIN sys.tables t ON ind.object_id = t.object_id
INNER JOIN sys.types y ON y.user_type_id = col.user_type_id
WHERE
t.is_ms_shipped = 0 AND
t.name = @table_name
ORDER BY
SchemaName,
t.name,
ind.name,
ic.index_column_id
您需要确保至少有一个索引包含datetimeColumn
ColumnOrder = 1
且未被禁用的索引。如果它已经存在,那么你的问题就在于其他地方,如果没有更多细节,我们将无法提供更多帮助。