У меня есть база данных SQL Server, в которой есть только одна таблица с несколькими столбцами. В настоящее время существует несколько тысяч строк. Столбцы следующие:
id (nvarchar(35))
path (nvarchar(255))
body (ntext)
datetimecreated (datetime)
author (nvarchar(255))
version (int)
summary (nvarchar(255))
Поисковый запрос следующий:
SELECT [id],[path],[body],[datetimecreated],[author],[version],[summary]
FROM [dbo].[pages] p1
where ([version] =
(select max(p2.[version])
from [dbo].[pages] p2
where p1.[path] = p2.[path]))
and (body like '%outlook%'
or summary like '%outlook%'
or author like '%outlook%'
)
order by p1.[path] asc
Поиск, подобный приведенному выше, займет 8-10 секунд. Я пробовал скопировать базу данных и преобразовать ntext в nvarchar(max) и не вижу разницы во времени запроса. Я также попытался создать полнотекстовый индекс и выполнить поиск по следующему:
contains (body, '"outlook"') or CONTAINS (summary, '"outlook"')
На самом деле это занимает больше времени.
Мне нужен совет/помощь, чтобы ускорить поисковые запросы. Я не проектировал базу данных.
Я попытался изменить столбец body на nvarchar(max) и создать полнотекстовый индекс, но безрезультатно.
Вот план выполнения:
<?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.589" Build = "16.0.5564.30211" xmlns = "http://schemas.microsoft.com/sqlserver/2004/07/showplan">
<BatchSequence>
<Batch>
<Statements>
<StmtSimple StatementCompId = "1" StatementEstRows = "1" StatementId = "1" StatementOptmLevel = "FULL" CardinalityEstimationModelVersion = "120" StatementSubTreeCost = "1.90059" StatementText = "SELECT TOP 1000 [id]
 ,[path]
 ,[body]
 ,[datetimecreated]
 ,[author]
 ,[version]
 ,[summary]
 FROM [dbo].[pages_1] p1
 where ([version] =
 (select max(p2.[version])
 from [dbo].[pages_1] p2
 where p1.[path] = p2.[path])) 
and (body like '%outlook%'
or summary like '%outlook%'
/*or author like '%outlook%'*/
)
order by p1.[path] asc" StatementType = "SELECT" QueryHash = "0x91AAE73160CEF12C" QueryPlanHash = "0xE33814DCBC42ED0F" RetrievedFromCache = "true" StatementSqlHandle = "0x09003CE69250B7708CCD87CBDE6C4A7A08DE0000000000000000000000000000000000000000000000000000" DatabaseContextSettingsId = "12" ParentObjectId = "0" StatementParameterizationType = "0" SecurityPolicyApplied = "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" MemoryGrant = "1424" CachedPlanSize = "48" CompileTime = "399" CompileCPU = "63" CompileMemory = "512">
<MemoryGrantInfo SerialRequiredMemory = "640" SerialDesiredMemory = "1424" RequiredMemory = "640" DesiredMemory = "1424" RequestedMemory = "1424" GrantWaitTime = "0" GrantedMemory = "1424" MaxUsedMemory = "520" MaxQueryMemory = "401408" />
<OptimizerHardwareDependentProperties EstimatedAvailableMemoryGrant = "47815008" EstimatedPagesCached = "5976876" EstimatedAvailableDegreeOfParallelism = "2" MaxCompileMemory = "1349624" />
<RelOp AvgRowSize = "4855" EstimateCPU = "1E-07" EstimateIO = "0" EstimateRebinds = "0" EstimateRewinds = "0" EstimatedExecutionMode = "Row" EstimateRows = "1" LogicalOp = "Top" NodeId = "0" Parallel = "false" PhysicalOp = "Top" EstimatedTotalSubtreeCost = "1.90059">
<OutputList>
<ColumnReference Database = "[wiki]" Schema = "[dbo]" Table = "[pages_1]" Alias = "[p1]" Column = "id" />
<ColumnReference Database = "[wiki]" Schema = "[dbo]" Table = "[pages_1]" Alias = "[p1]" Column = "path" />
<ColumnReference Database = "[wiki]" Schema = "[dbo]" Table = "[pages_1]" Alias = "[p1]" Column = "body" />
<ColumnReference Database = "[wiki]" Schema = "[dbo]" Table = "[pages_1]" Alias = "[p1]" Column = "datetimecreated" />
<ColumnReference Database = "[wiki]" Schema = "[dbo]" Table = "[pages_1]" Alias = "[p1]" Column = "author" />
<ColumnReference Database = "[wiki]" Schema = "[dbo]" Table = "[pages_1]" Alias = "[p1]" Column = "version" />
<ColumnReference Database = "[wiki]" Schema = "[dbo]" Table = "[pages_1]" Alias = "[p1]" Column = "summary" />
</OutputList>
<RunTimeInformation>
<RunTimeCountersPerThread Thread = "0" ActualRows = "4" Batches = "0" ActualEndOfScans = "1" ActualExecutions = "1" ActualExecutionMode = "Row" ActualElapsedms = "8595" ActualCPUms = "701" />
</RunTimeInformation>
<Top RowCount = "false" IsPercent = "false" WithTies = "false">
<TopExpression>
<ScalarOperator ScalarString = "(1000)">
<Const ConstValue = "(1000)" />
</ScalarOperator>
</TopExpression>
<RelOp AvgRowSize = "4855" EstimateCPU = "0.00586661" EstimateIO = "0" EstimateRebinds = "0" EstimateRewinds = "0" EstimatedExecutionMode = "Row" EstimateRows = "1" LogicalOp = "Inner Join" NodeId = "1" Parallel = "false" PhysicalOp = "Merge Join" EstimatedTotalSubtreeCost = "1.90059">
<OutputList>
<ColumnReference Database = "[wiki]" Schema = "[dbo]" Table = "[pages_1]" Alias = "[p1]" Column = "id" />
<ColumnReference Database = "[wiki]" Schema = "[dbo]" Table = "[pages_1]" Alias = "[p1]" Column = "path" />
<ColumnReference Database = "[wiki]" Schema = "[dbo]" Table = "[pages_1]" Alias = "[p1]" Column = "body" />
<ColumnReference Database = "[wiki]" Schema = "[dbo]" Table = "[pages_1]" Alias = "[p1]" Column = "datetimecreated" />
<ColumnReference Database = "[wiki]" Schema = "[dbo]" Table = "[pages_1]" Alias = "[p1]" Column = "author" />
<ColumnReference Database = "[wiki]" Schema = "[dbo]" Table = "[pages_1]" Alias = "[p1]" Column = "version" />
<ColumnReference Database = "[wiki]" Schema = "[dbo]" Table = "[pages_1]" Alias = "[p1]" Column = "summary" />
</OutputList>
<RunTimeInformation>
<RunTimeCountersPerThread Thread = "0" ActualRows = "4" Batches = "0" ActualEndOfScans = "1" ActualExecutions = "1" ActualExecutionMode = "Row" ActualElapsedms = "8595" ActualCPUms = "701" ActualScans = "0" ActualLogicalReads = "0" ActualPhysicalReads = "0" ActualReadAheads = "0" ActualLobLogicalReads = "0" ActualLobPhysicalReads = "0" ActualLobReadAheads = "0" />
</RunTimeInformation>
<Merge ManyToMany = "false">
<InnerSideJoinColumns>
<ColumnReference Database = "[wiki]" Schema = "[dbo]" Table = "[pages_1]" Alias = "[p1]" Column = "path" />
</InnerSideJoinColumns>
<OuterSideJoinColumns>
<ColumnReference Database = "[wiki]" Schema = "[dbo]" Table = "[pages_1]" Alias = "[p2]" Column = "path" />
</OuterSideJoinColumns>
<Residual>
<ScalarOperator ScalarString = "[Expr1002]=[wiki].[dbo].[pages_1].[version] as [p1].[version] AND [wiki].[dbo].[pages_1].[path] as [p2].[path]=[wiki].[dbo].[pages_1].[path] as [p1].[path]">
<Logical Operation = "AND">
<ScalarOperator>
<Compare CompareOp = "EQ">
<ScalarOperator>
<Identifier>
<ColumnReference Column = "Expr1002" />
</Identifier>
</ScalarOperator>
<ScalarOperator>
<Identifier>
<ColumnReference Database = "[wiki]" Schema = "[dbo]" Table = "[pages_1]" Alias = "[p1]" Column = "version" />
</Identifier>
</ScalarOperator>
</Compare>
</ScalarOperator>
<ScalarOperator>
<Compare CompareOp = "EQ">
<ScalarOperator>
<Identifier>
<ColumnReference Database = "[wiki]" Schema = "[dbo]" Table = "[pages_1]" Alias = "[p2]" Column = "path" />
</Identifier>
</ScalarOperator>
<ScalarOperator>
<Identifier>
<ColumnReference Database = "[wiki]" Schema = "[dbo]" Table = "[pages_1]" Alias = "[p1]" Column = "path" />
</Identifier>
</ScalarOperator>
</Compare>
</ScalarOperator>
</Logical>
</ScalarOperator>
</Residual>
<RelOp AvgRowSize = "65" EstimateCPU = "0.0016498" EstimateIO = "0" EstimateRebinds = "0" EstimateRewinds = "0" EstimatedExecutionMode = "Row" EstimateRows = "98" LogicalOp = "Aggregate" NodeId = "2" Parallel = "false" PhysicalOp = "Stream Aggregate" EstimatedTotalSubtreeCost = "0.969562">
<OutputList>
<ColumnReference Database = "[wiki]" Schema = "[dbo]" Table = "[pages_1]" Alias = "[p2]" Column = "path" />
<ColumnReference Column = "Expr1002" />
</OutputList>
<RunTimeInformation>
<RunTimeCountersPerThread Thread = "0" ActualRows = "98" Batches = "0" ActualEndOfScans = "1" ActualExecutions = "1" ActualExecutionMode = "Row" ActualElapsedms = "3" ActualCPUms = "3" />
</RunTimeInformation>
<StreamAggregate>
<DefinedValues>
<DefinedValue>
<ColumnReference Column = "Expr1002" />
<ScalarOperator ScalarString = "MAX([wiki].[dbo].[pages_1].[version] as [p2].[version])">
<Aggregate AggType = "MAX" Distinct = "false">
<ScalarOperator>
<Identifier>
<ColumnReference Database = "[wiki]" Schema = "[dbo]" Table = "[pages_1]" Alias = "[p2]" Column = "version" />
</Identifier>
</ScalarOperator>
</Aggregate>
</ScalarOperator>
</DefinedValue>
</DefinedValues>
<GroupBy>
<ColumnReference Database = "[wiki]" Schema = "[dbo]" Table = "[pages_1]" Alias = "[p2]" Column = "path" />
</GroupBy>
<RelOp AvgRowSize = "65" EstimateCPU = "0.047471" EstimateIO = "0.0112613" EstimateRebinds = "0" EstimateRewinds = "0" EstimatedExecutionMode = "Row" EstimateRows = "2668" LogicalOp = "Sort" NodeId = "3" Parallel = "false" PhysicalOp = "Sort" EstimatedTotalSubtreeCost = "0.967912">
<OutputList>
<ColumnReference Database = "[wiki]" Schema = "[dbo]" Table = "[pages_1]" Alias = "[p2]" Column = "path" />
<ColumnReference Database = "[wiki]" Schema = "[dbo]" Table = "[pages_1]" Alias = "[p2]" Column = "version" />
</OutputList>
<MemoryFractions Input = "1" Output = "0.734694" />
<RunTimeInformation>
<RunTimeCountersPerThread Thread = "0" ActualRebinds = "1" ActualRewinds = "0" ActualRows = "2668" Batches = "0" ActualEndOfScans = "1" ActualExecutions = "1" ActualExecutionMode = "Row" ActualElapsedms = "3" ActualCPUms = "3" ActualScans = "0" ActualLogicalReads = "0" ActualPhysicalReads = "0" ActualReadAheads = "0" ActualLobLogicalReads = "0" ActualLobPhysicalReads = "0" ActualLobReadAheads = "0" InputMemoryGrant = "1296" OutputMemoryGrant = "704" UsedMemoryGrant = "280" />
</RunTimeInformation>
<Sort Distinct = "false">
<OrderBy>
<OrderByColumn Ascending = "true">
<ColumnReference Database = "[wiki]" Schema = "[dbo]" Table = "[pages_1]" Alias = "[p2]" Column = "path" />
</OrderByColumn>
</OrderBy>
<RelOp AvgRowSize = "65" EstimateCPU = "0.0030918" EstimateIO = "0.906088" EstimateRebinds = "0" EstimateRewinds = "0" EstimatedExecutionMode = "Row" EstimateRows = "2668" LogicalOp = "Clustered Index Scan" NodeId = "4" Parallel = "false" PhysicalOp = "Clustered Index Scan" EstimatedTotalSubtreeCost = "0.90918" TableCardinality = "2668">
<OutputList>
<ColumnReference Database = "[wiki]" Schema = "[dbo]" Table = "[pages_1]" Alias = "[p2]" Column = "path" />
<ColumnReference Database = "[wiki]" Schema = "[dbo]" Table = "[pages_1]" Alias = "[p2]" Column = "version" />
</OutputList>
<RunTimeInformation>
<RunTimeCountersPerThread Thread = "0" ActualRows = "2668" ActualRowsRead = "2668" Batches = "0" ActualEndOfScans = "1" ActualExecutions = "1" ActualExecutionMode = "Row" ActualElapsedms = "1" ActualCPUms = "1" ActualScans = "1" ActualLogicalReads = "1247" ActualPhysicalReads = "0" ActualReadAheads = "0" ActualLobLogicalReads = "0" ActualLobPhysicalReads = "0" ActualLobReadAheads = "0" />
</RunTimeInformation>
<IndexScan Ordered = "false" ForcedIndex = "false" ForceScan = "false" NoExpandHint = "false" Storage = "RowStore">
<DefinedValues>
<DefinedValue>
<ColumnReference Database = "[wiki]" Schema = "[dbo]" Table = "[pages_1]" Alias = "[p2]" Column = "path" />
</DefinedValue>
<DefinedValue>
<ColumnReference Database = "[wiki]" Schema = "[dbo]" Table = "[pages_1]" Alias = "[p2]" Column = "version" />
</DefinedValue>
</DefinedValues>
<Object Database = "[wiki]" Schema = "[dbo]" Table = "[pages_1]" Index = "[PK_pages_1]" Alias = "[p2]" IndexKind = "Clustered" Storage = "RowStore" />
</IndexScan>
</RelOp>
</Sort>
</RelOp>
</StreamAggregate>
</RelOp>
<RelOp AvgRowSize = "4855" EstimateCPU = "0.000235967" EstimateIO = "0.0112613" EstimateRebinds = "0" EstimateRewinds = "0" EstimatedExecutionMode = "Row" EstimateRows = "19.5838" LogicalOp = "Sort" NodeId = "5" Parallel = "false" PhysicalOp = "Sort" EstimatedTotalSubtreeCost = "0.925159">
<OutputList>
<ColumnReference Database = "[wiki]" Schema = "[dbo]" Table = "[pages_1]" Alias = "[p1]" Column = "id" />
<ColumnReference Database = "[wiki]" Schema = "[dbo]" Table = "[pages_1]" Alias = "[p1]" Column = "path" />
<ColumnReference Database = "[wiki]" Schema = "[dbo]" Table = "[pages_1]" Alias = "[p1]" Column = "body" />
<ColumnReference Database = "[wiki]" Schema = "[dbo]" Table = "[pages_1]" Alias = "[p1]" Column = "datetimecreated" />
<ColumnReference Database = "[wiki]" Schema = "[dbo]" Table = "[pages_1]" Alias = "[p1]" Column = "author" />
<ColumnReference Database = "[wiki]" Schema = "[dbo]" Table = "[pages_1]" Alias = "[p1]" Column = "version" />
<ColumnReference Database = "[wiki]" Schema = "[dbo]" Table = "[pages_1]" Alias = "[p1]" Column = "summary" />
</OutputList>
<MemoryFractions Input = "0.265306" Output = "0.265306" />
<RunTimeInformation>
<RunTimeCountersPerThread Thread = "0" ActualRebinds = "1" ActualRewinds = "0" ActualRows = "79" Batches = "0" ActualEndOfScans = "1" ActualExecutions = "1" ActualExecutionMode = "Row" ActualElapsedms = "8592" ActualCPUms = "697" ActualScans = "0" ActualLogicalReads = "0" ActualPhysicalReads = "0" ActualReadAheads = "0" ActualLobLogicalReads = "0" ActualLobPhysicalReads = "0" ActualLobReadAheads = "0" InputMemoryGrant = "712" OutputMemoryGrant = "328" UsedMemoryGrant = "240" />
</RunTimeInformation>
<Sort Distinct = "false">
<OrderBy>
<OrderByColumn Ascending = "true">
<ColumnReference Database = "[wiki]" Schema = "[dbo]" Table = "[pages_1]" Alias = "[p1]" Column = "path" />
</OrderByColumn>
</OrderBy>
<RelOp AvgRowSize = "4855" EstimateCPU = "0.00448224" EstimateIO = "0" EstimateRebinds = "0" EstimateRewinds = "0" EstimatedExecutionMode = "Row" EstimateRows = "19.5838" LogicalOp = "Filter" NodeId = "6" Parallel = "false" PhysicalOp = "Filter" EstimatedTotalSubtreeCost = "0.913662">
<OutputList>
<ColumnReference Database = "[wiki]" Schema = "[dbo]" Table = "[pages_1]" Alias = "[p1]" Column = "id" />
<ColumnReference Database = "[wiki]" Schema = "[dbo]" Table = "[pages_1]" Alias = "[p1]" Column = "path" />
<ColumnReference Database = "[wiki]" Schema = "[dbo]" Table = "[pages_1]" Alias = "[p1]" Column = "body" />
<ColumnReference Database = "[wiki]" Schema = "[dbo]" Table = "[pages_1]" Alias = "[p1]" Column = "datetimecreated" />
<ColumnReference Database = "[wiki]" Schema = "[dbo]" Table = "[pages_1]" Alias = "[p1]" Column = "author" />
<ColumnReference Database = "[wiki]" Schema = "[dbo]" Table = "[pages_1]" Alias = "[p1]" Column = "version" />
<ColumnReference Database = "[wiki]" Schema = "[dbo]" Table = "[pages_1]" Alias = "[p1]" Column = "summary" />
</OutputList>
<RunTimeInformation>
<RunTimeCountersPerThread Thread = "0" ActualRows = "79" Batches = "0" ActualEndOfScans = "1" ActualExecutions = "1" ActualExecutionMode = "Row" ActualElapsedms = "8591" ActualCPUms = "697" />
</RunTimeInformation>
<Filter StartupExpression = "false">
<RelOp AvgRowSize = "4855" EstimateCPU = "0.0030918" EstimateIO = "0.906088" EstimateRebinds = "0" EstimateRewinds = "0" EstimatedExecutionMode = "Row" EstimateRows = "2668" LogicalOp = "Clustered Index Scan" NodeId = "7" Parallel = "false" PhysicalOp = "Clustered Index Scan" EstimatedTotalSubtreeCost = "0.90918" TableCardinality = "2668">
<OutputList>
<ColumnReference Database = "[wiki]" Schema = "[dbo]" Table = "[pages_1]" Alias = "[p1]" Column = "id" />
<ColumnReference Database = "[wiki]" Schema = "[dbo]" Table = "[pages_1]" Alias = "[p1]" Column = "path" />
<ColumnReference Database = "[wiki]" Schema = "[dbo]" Table = "[pages_1]" Alias = "[p1]" Column = "body" />
<ColumnReference Database = "[wiki]" Schema = "[dbo]" Table = "[pages_1]" Alias = "[p1]" Column = "datetimecreated" />
<ColumnReference Database = "[wiki]" Schema = "[dbo]" Table = "[pages_1]" Alias = "[p1]" Column = "author" />
<ColumnReference Database = "[wiki]" Schema = "[dbo]" Table = "[pages_1]" Alias = "[p1]" Column = "version" />
<ColumnReference Database = "[wiki]" Schema = "[dbo]" Table = "[pages_1]" Alias = "[p1]" Column = "summary" />
</OutputList>
<RunTimeInformation>
<RunTimeCountersPerThread Thread = "0" ActualRows = "2668" ActualRowsRead = "2668" Batches = "0" ActualEndOfScans = "1" ActualExecutions = "1" ActualExecutionMode = "Row" ActualElapsedms = "653" ActualCPUms = "3" ActualScans = "1" ActualLogicalReads = "1247" ActualPhysicalReads = "0" ActualReadAheads = "0" ActualLobLogicalReads = "0" ActualLobPhysicalReads = "0" ActualLobReadAheads = "0" />
</RunTimeInformation>
<IndexScan Ordered = "false" ForcedIndex = "false" ForceScan = "false" NoExpandHint = "false" Storage = "RowStore">
<DefinedValues>
<DefinedValue>
<ColumnReference Database = "[wiki]" Schema = "[dbo]" Table = "[pages_1]" Alias = "[p1]" Column = "id" />
</DefinedValue>
<DefinedValue>
<ColumnReference Database = "[wiki]" Schema = "[dbo]" Table = "[pages_1]" Alias = "[p1]" Column = "path" />
</DefinedValue>
<DefinedValue>
<ColumnReference Database = "[wiki]" Schema = "[dbo]" Table = "[pages_1]" Alias = "[p1]" Column = "body" />
</DefinedValue>
<DefinedValue>
<ColumnReference Database = "[wiki]" Schema = "[dbo]" Table = "[pages_1]" Alias = "[p1]" Column = "datetimecreated" />
</DefinedValue>
<DefinedValue>
<ColumnReference Database = "[wiki]" Schema = "[dbo]" Table = "[pages_1]" Alias = "[p1]" Column = "author" />
</DefinedValue>
<DefinedValue>
<ColumnReference Database = "[wiki]" Schema = "[dbo]" Table = "[pages_1]" Alias = "[p1]" Column = "version" />
</DefinedValue>
<DefinedValue>
<ColumnReference Database = "[wiki]" Schema = "[dbo]" Table = "[pages_1]" Alias = "[p1]" Column = "summary" />
</DefinedValue>
</DefinedValues>
<Object Database = "[wiki]" Schema = "[dbo]" Table = "[pages_1]" Index = "[PK_pages_1]" Alias = "[p1]" IndexKind = "Clustered" Storage = "RowStore" />
</IndexScan>
</RelOp>
<Predicate>
<ScalarOperator ScalarString = "[wiki].[dbo].[pages_1].[body] as [p1].[body] like N'%outlook%' OR [wiki].[dbo].[pages_1].[summary] as [p1].[summary] like N'%outlook%'">
<Logical Operation = "OR">
<ScalarOperator>
<Intrinsic FunctionName = "like">
<ScalarOperator>
<Identifier>
<ColumnReference Database = "[wiki]" Schema = "[dbo]" Table = "[pages_1]" Alias = "[p1]" Column = "body" />
</Identifier>
</ScalarOperator>
<ScalarOperator>
<Const ConstValue = "N'%outlook%'" />
</ScalarOperator>
</Intrinsic>
</ScalarOperator>
<ScalarOperator>
<Intrinsic FunctionName = "like">
<ScalarOperator>
<Identifier>
<ColumnReference Database = "[wiki]" Schema = "[dbo]" Table = "[pages_1]" Alias = "[p1]" Column = "summary" />
</Identifier>
</ScalarOperator>
<ScalarOperator>
<Const ConstValue = "N'%outlook%'" />
</ScalarOperator>
</Intrinsic>
</ScalarOperator>
</Logical>
</ScalarOperator>
</Predicate>
</Filter>
</RelOp>
</Sort>
</RelOp>
</Merge>
</RelOp>
</Top>
</RelOp>
</QueryPlan>
</StmtSimple>
</Statements>
</Batch>
</BatchSequence>
</ShowPlanXML>
Независимо от окончательного решения, вам, вероятно, следует перейти от типов данных image
, ntext
и text
, поскольку они устарели, по крайней мере, с SQL Server 2005 (перейдите на varbinary(max)
, nvarchar(max)
и varchar(max)
соответственно). Ссылка: ntext, text и image (Transact-SQL).
Хотя в некоторых ситуациях полнотекстовый поиск может быть полезен, он не всегда волшебным образом повышает производительность. См., например: Почему полнотекстовые запросы CONTAINS такие медленные.
Любой запрос фрагмента строки внутри более крупной строки, скорее всего, будет медленным.
Вы уверены, что опубликованный вами план выполнения предназначен для полнотекстового индекса? Потому что все, что я вижу, это сканы таблиц.
Содержит не может выполнять поиск по подстановочному знаку. Запросы такого типа всегда будут медленными, единственное решение — создать индекс, содержащий текстовые столбцы, чтобы ему, по крайней мере, не приходилось просматривать кластеризованный столбец, но это также может не помочь.
Судя по вашему медленному результату, похоже, что путь тоже не индексируется. Возможно, разобьем ваш запрос на два: первый извлекает последнюю версию, а второй выполняет сопоставление текста.
Представленный план выполнения запроса показывает, что 96% времени (стоимости) тратится на выборку строки с максимальной версией. Мне это кажется маловероятным. Однако попробуйте сделать выбор, используя row_number() (разделение по порядку пути по описанию версии) rn и rn=1. И предоставить актуальные данные об исполнении запроса
@AlwaysLearning понял, и да, я делаю это с этой БД, хотя на производительность это не влияет.
@siggemannen спасибо за идею. Я сделал первый запрос, который получает последнюю версию всех страниц, а затем второй, который запрашивает набор результатов из первого по поисковому запросу. Общее время моего тестирования сократилось примерно до 2 секунд (в 4 раза быстрее)!
В вашем запросе могут быть два улучшения.
Ниже приведен измененный запрос, который вы можете использовать. Если вы не собираетесь использовать индекс, используйте Like вместо contains, так как это может быть накладным, но если вы используете индекс, вы можете использовать его, чтобы получить всю мощь индекса.
SELECT [id],[path],[body],[datetimecreated],[author],[version],[summary]
FROM [dbo].[pages] p1
INNER JOIN
(select max(p2.[version]) as latest_version, p2.[path] as path
from [dbo].[pages] p2
group by p2.[path]
) X ON X.path = p1.path and X.latest_version = p1.version
where contains (body, '"outlook"')
order by p1.[path] asc
UNION
SELECT [id],[path],[body],[datetimecreated],[author],[version],[summary]
FROM [dbo].[pages] p1
INNER JOIN
(select max(p2.[version]) as latest_version, p2.[path] as path
from [dbo].[pages] p2
group by p2.[path]
) X ON X.path = p1.path and X.latest_version = p1.version
where CONTAINS(summary, '"outlook"')
order by p1.[path] asc
UNION
SELECT [id],[path],[body],[datetimecreated],[author],[version],[summary]
FROM [dbo].[pages] p1
INNER JOIN
(select max(p2.[version]) as latest_version, p2.[path] as path
from [dbo].[pages] p2
group by p2.[path]
) X ON X.path = p1.path and X.latest_version = p1.version
where CONTAINS (author, '"outlook"')
order by p1.[path] asc
Попробовал ваш запрос, производительность не улучшилась, но спасибо за идею!
Сначала я преобразовал поле body в varchar(max) (что не дало никакого увеличения производительности), а затем разбил его на два запроса, первый из которых получает последнюю версию каждой страницы, а второй представляет собой запрос запросов, который ищет поисковая фраза. В результате получается в среднем 2 секунды на результат, что означает увеличение скорости в 4-5 раз. Спасибо!
Первый запрос:
select [id], [path], [body], [datetimecreated], [author], [version], [summary]
from pages p1
where (version =
(select max(p2.version)
from pages p2
where p1.path = p2.path))
order by p1.path asc
Второй запрос:
select id, path, datetimecreated, version
from latest
where (body like '%outlook%'
or summary like '%outlook%')
order by path asc
Пожалуйста, используйте brentozar.com/pastetheplan, чтобы вставить свой план.