Bla*_*olf 8 sql-server stored-procedures t-sql sql-server-2014
我试图从表中查询 0 到 65,000 行。
服务器使用的是Microsoft SQL Server 2014,我无法更改服务器上的硬件。
架构
[Id] (PK) INT
[varchar1] VARCHAR(4) Normal Cardinality
[varchar2] VARCHAR(250) Normal Cardinality
[varchar3] VARCHAR(250) Normal Cardinality
[varchar4] VARCHAR(100) Normal Cardinality
[date1] DATETIME High Cardinality
[varchar5] VARCHAR(100) Low Cardinality
[varchar6] VARCHAR(1000) Normal Cardinality
[varchar7] VARCHAR(100) Normal Cardinality
[varchar8] VARCHAR(20) Normal Cardinality
[varchar9] VARCHAR(100) High Cardinality
[xml1] XML Low Cardinality
Run Code Online (Sandbox Code Playgroud)
询问
以下查询是存储过程的一部分(其余部分无关紧要,因为它对存储过程的性能影响不大)。列名称已替换为列类型和编号:
SELECT [varchar1]
, [varchar4]
, [date1]
, [varchar5]
, [varchar6]
, [varchar7]
, [varchar8]
, [varchar9]
, [xml1]
FROM [database].[dbo].[table] WITH (NOLOCK)
WHERE [varchar1] = '0'
AND ([date1] >='2014-1-1' AND [date1] <= '2017-1-1')
AND [varchar8] = 'someText'
AND [varchar9] LIKE '%a%'
ORDER BY [varchar1] ASC, [date1] DESC
OFFSET 0 ROWS
FETCH NEXT 65000 ROWS ONLY
Run Code Online (Sandbox Code Playgroud)
执行计划
执行计划 XML:https : //gist.github.com/BlackyWolf/046856518065bfe5293cad78f73340e9
但到目前为止它提供的信息是:
Query1: Query cost (relative to the batch): 100%
Index Seek [NonClustered]
SELECT Top [Table].[i_table_index]
Cost: 0% Cost: 4% Cost: 96%
Run Code Online (Sandbox Code Playgroud)
我没有在此搜索中使用 PK。此查询具有以下持续时间,具体取决于删除的列:
select 语句中的所有列 = 18s-27s 没有 [xml1] = 8s-11s 没有 [xml1] 和 [varchar4] = 4s-6s
从 Web 到 DB 再返回的总执行时间需要在 10 秒内。最好这个查询需要在 4s 之内。
返回大小 (MB)
我希望返回价值 290-310 MB 的数据,误差幅度为 20 MB,总共 65,000 条记录。
指数
主键上有一个聚集索引。
有一个非聚集索引定义为:
CREATE NONCLUSTERED INDEX [i_table_index]
ON dbo.[table] ([varchar1], [date1] DESC, [varchar8], [varchar9])
INCLUDE ([varchar4], [varchar7], [xml1]);
Run Code Online (Sandbox Code Playgroud)
不幸的是,我无法真正删除[xml1]
或[varchar4]
或我会。说实话,索引似乎没有多大帮助,即使执行计划显示它正在使用它。
我的 SQL 经验仅限于我使用 C# 所做的事情。感谢您提供的任何帮助或指导(甚至是链接),如果您需要更多信息,请告诉我,我会尽力获取。
小智 1
where 子句中的每个元素都使用函数。当使用函数时,sql无法确定使用什么索引。它无法确定 where 子句中的哪些字段导致表扫描。