提高查询性能 - T-SQL

时间:2018-03-12 14:38:54

标签: sql performance tsql

我有一个已经按“datetime”列排序的表格。因为插入时我会存储UTC日期,所以它是有序的。这是一张人口稠密的桌子。所以我试图提高查询性能,如果可能的话。

当我使用WHERE columnDateTime > dateToSearch时,返回行需要很长时间。由于我的表已按columnDateTime排序,我该怎么做才能提高查询性能。例如,当一个表按cod排序并且您尝试搜索cod > 40时,T-SQL优化会在找到cod = 41时停止搜索并返回表的其余部分,因为它知道该表是由该索引排序的。这是一种可以告诉T-SQL我的表已经由columnDateTime订购的方法吗?

1 个答案:

答案 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且未被禁用的索引。如果它已经存在,那么你的问题就在于其他地方,如果没有更多细节,我们将无法提供更多帮助。