当我运行以下查询时服务器重启后,需要很长时间。该表有1.500.000行,查询返回140.000行。
select
Oid, -- Primary Key
IsTranslated -- bool(bit) column
from Translation
where [Language] = '24648b4e-05ac-42cb-b6cf-c1167b6a41b7'
“语言”列上有一个索引。服务器重启后的第一次运行需要6分钟才能完成,后续查询需要1-2秒才能完成。将“WITH(INDEX(iLanguage_Translation))”添加到查询的FROM部分并没有提高性能。
但是,在服务器重启后第一次运行时,follownig查询只需2秒即可完成:
select Oid -- Primary Key
from Translation
where [Language] = '24648b4e-05ac-42cb-b6cf-c1167b6a41b7'
两个查询之间的唯一区别是一个额外的bool(位)列。为什么140,000行额外位列的传输需要6分钟?
我的SQL Server 2014配备了i7 2700K处理器和16GB内存。
这是表创建脚本:
CREATE TABLE [dbo].[Translation](
[Oid] [uniqueidentifier] ROWGUIDCOL NOT NULL,
[PropertyName] [nvarchar](max) NULL,
[DefaultLanguageValue] [nvarchar](max) NULL,
[TranslatedValue] [nvarchar](max) NULL,
[IsTranslated] [bit] NULL,
[NodePath] [nvarchar](max) NULL,
[Description] [nvarchar](max) NULL,
[Language] [uniqueidentifier] NULL,
[OptimisticLockField] [int] NULL,
[GCRecord] [int] NULL,
CONSTRAINT [PK_Translation] PRIMARY KEY CLUSTERED
(
[Oid] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
/****** Object: Index [iGCRecord_Translation] Script Date: 2016.07.21. 12:09:08 ******/
CREATE NONCLUSTERED INDEX [iGCRecord_Translation] ON [dbo].[Translation]
(
[GCRecord] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
/****** Object: Index [iLanguage_Translation] Script Date: 2016.07.21. 12:09:08 ******/
CREATE NONCLUSTERED INDEX [iLanguage_Translation] ON [dbo].[Translation]
(
[Language] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
ALTER TABLE [dbo].[Translation] WITH NOCHECK ADD CONSTRAINT [FK_Translation_Language] FOREIGN KEY([Language])
REFERENCES [dbo].[Language] ([Oid])
NOT FOR REPLICATION
GO
ALTER TABLE [dbo].[Translation] CHECK CONSTRAINT [FK_Translation_Language]
GO
将在我的网络应用中使用的最终查询使用表格的所有列:
SELECT [Oid]
,[PropertyName]
,[DefaultLanguageValue]
,[TranslatedValue]
,[IsTranslated]
,[NodePath]
,[Description]
,[Language]
,[OptimisticLockField]
,[GCRecord]
FROM [dbo].[Translation]
where [Language] = '24648b4e-05ac-42cb-b6cf-c1167b6a41b7'
执行计划:
执行计划XML:
<?xml version="1.0" encoding="utf-16"?>
<ShowPlanXML xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" Version="1.2" Build="12.0.4459.0" xmlns="http://schemas.microsoft.com/sqlserver/2004/07/showplan">
<BatchSequence>
<Batch>
<Statements>
<StmtSimple StatementCompId="1" StatementEstRows="171288" StatementId="1" StatementOptmLevel="FULL" CardinalityEstimationModelVersion="120" StatementSubTreeCost="102.045" StatementText="SELECT [Oid],[PropertyName],[DefaultLanguageValue],[TranslatedValue],[IsTranslated],[NodePath],[Description],[Language],[OptimisticLockField],[GCRecord] FROM [dbo].[Translation] WHERE [Language]=@1" StatementType="SELECT" QueryHash="0x7722D3C37A4ACDF4" QueryPlanHash="0xEBAED5C218B1FD8D" RetrievedFromCache="false">
<StatementSetOptions ANSI_NULLS="true" ANSI_PADDING="true" ANSI_WARNINGS="true" ARITHABORT="true" CONCAT_NULL_YIELDS_NULL="true" NUMERIC_ROUNDABORT="false" QUOTED_IDENTIFIER="true" />
<QueryPlan DegreeOfParallelism="1" CachedPlanSize="24" CompileTime="475" CompileCPU="2" CompileMemory="184">
<MemoryGrantInfo SerialRequiredMemory="0" SerialDesiredMemory="0" />
<OptimizerHardwareDependentProperties EstimatedAvailableMemoryGrant="209425" EstimatedPagesCached="104712" EstimatedAvailableDegreeOfParallelism="4" />
<RelOp AvgRowSize="20181" EstimateCPU="2.07874" EstimateIO="99.9661" EstimateRebinds="0" EstimateRewinds="0" EstimatedExecutionMode="Row" EstimateRows="171288" LogicalOp="Clustered Index Scan" NodeId="0" Parallel="false" PhysicalOp="Clustered Index Scan" EstimatedTotalSubtreeCost="102.045" TableCardinality="1889620">
<OutputList>
<ColumnReference Database="[vintocon.archifm.Loc]" Schema="[dbo]" Table="[Translation]" Column="Oid" />
<ColumnReference Database="[vintocon.archifm.Loc]" Schema="[dbo]" Table="[Translation]" Column="PropertyName" />
<ColumnReference Database="[vintocon.archifm.Loc]" Schema="[dbo]" Table="[Translation]" Column="DefaultLanguageValue" />
<ColumnReference Database="[vintocon.archifm.Loc]" Schema="[dbo]" Table="[Translation]" Column="TranslatedValue" />
<ColumnReference Database="[vintocon.archifm.Loc]" Schema="[dbo]" Table="[Translation]" Column="IsTranslated" />
<ColumnReference Database="[vintocon.archifm.Loc]" Schema="[dbo]" Table="[Translation]" Column="NodePath" />
<ColumnReference Database="[vintocon.archifm.Loc]" Schema="[dbo]" Table="[Translation]" Column="Description" />
<ColumnReference Database="[vintocon.archifm.Loc]" Schema="[dbo]" Table="[Translation]" Column="Language" />
<ColumnReference Database="[vintocon.archifm.Loc]" Schema="[dbo]" Table="[Translation]" Column="OptimisticLockField" />
<ColumnReference Database="[vintocon.archifm.Loc]" Schema="[dbo]" Table="[Translation]" Column="GCRecord" />
</OutputList>
<RunTimeInformation>
<RunTimeCountersPerThread Thread="0" ActualRows="144003" ActualEndOfScans="1" ActualExecutions="1" />
</RunTimeInformation>
<IndexScan Ordered="false" ForcedIndex="false" ForceScan="false" NoExpandHint="false" Storage="RowStore">
<DefinedValues>
<DefinedValue>
<ColumnReference Database="[vintocon.archifm.Loc]" Schema="[dbo]" Table="[Translation]" Column="Oid" />
</DefinedValue>
<DefinedValue>
<ColumnReference Database="[vintocon.archifm.Loc]" Schema="[dbo]" Table="[Translation]" Column="PropertyName" />
</DefinedValue>
<DefinedValue>
<ColumnReference Database="[vintocon.archifm.Loc]" Schema="[dbo]" Table="[Translation]" Column="DefaultLanguageValue" />
</DefinedValue>
<DefinedValue>
<ColumnReference Database="[vintocon.archifm.Loc]" Schema="[dbo]" Table="[Translation]" Column="TranslatedValue" />
</DefinedValue>
<DefinedValue>
<ColumnReference Database="[vintocon.archifm.Loc]" Schema="[dbo]" Table="[Translation]" Column="IsTranslated" />
</DefinedValue>
<DefinedValue>
<ColumnReference Database="[vintocon.archifm.Loc]" Schema="[dbo]" Table="[Translation]" Column="NodePath" />
</DefinedValue>
<DefinedValue>
<ColumnReference Database="[vintocon.archifm.Loc]" Schema="[dbo]" Table="[Translation]" Column="Description" />
</DefinedValue>
<DefinedValue>
<ColumnReference Database="[vintocon.archifm.Loc]" Schema="[dbo]" Table="[Translation]" Column="Language" />
</DefinedValue>
<DefinedValue>
<ColumnReference Database="[vintocon.archifm.Loc]" Schema="[dbo]" Table="[Translation]" Column="OptimisticLockField" />
</DefinedValue>
<DefinedValue>
<ColumnReference Database="[vintocon.archifm.Loc]" Schema="[dbo]" Table="[Translation]" Column="GCRecord" />
</DefinedValue>
</DefinedValues>
<Object Database="[vintocon.archifm.Loc]" Schema="[dbo]" Table="[Translation]" Index="[PK_Translation]" IndexKind="Clustered" Storage="RowStore" />
<Predicate>
<ScalarOperator ScalarString="[vintocon.archifm.Loc].[dbo].[Translation].[Language]={guid'24648B4E-05AC-42CB-B6CF-C1167B6A41B7'}">
<Compare CompareOp="EQ">
<ScalarOperator>
<Identifier>
<ColumnReference Database="[vintocon.archifm.Loc]" Schema="[dbo]" Table="[Translation]" Column="Language" />
</Identifier>
</ScalarOperator>
<ScalarOperator>
<Const ConstValue="{guid'24648B4E-05AC-42CB-B6CF-C1167B6A41B7'}" />
</ScalarOperator>
</Compare>
</ScalarOperator>
</Predicate>
</IndexScan>
</RelOp>
<ParameterList>
<ColumnReference Column="@1" ParameterCompiledValue="'24648b4e-05ac-42cb-b6cf-c1167b6a41b7'" ParameterRuntimeValue="'24648b4e-05ac-42cb-b6cf-c1167b6a41b7'" />
</ParameterList>
</QueryPlan>
</StmtSimple>
</Statements>
</Batch>
</BatchSequence>
</ShowPlanXML>
答案 0 :(得分:2)
阅读有关执行计划的KeyLookup
操作并创建覆盖索引:
CREATE NONCLUSTERED INDEX [iLanguage_Translation]
ON [dbo].[Translation] ([Language]) INCLUDE (IsTranslated)