Все технические форумы на одном сайте Удобный поиск информации с популярных форумов в одном месте
Вопрос: разные планы выполнения одного запроса - как заставить CBO взять правильный? (10g!)

один и тот же запрос выполняю в SQL Plus (выполняется отлично!) и в моей программулине (выполняется плохо). В V$SQLAREA вижу два SQL_ID с разными планами выполнения. Разница в планах (смотрел dbms_xplan.display_cursor('5nx8hn25yux4b','','typical')) видна невооруженным глазом: хороший берет селективный индекс в большой таблице (в предикате стоит соответствующий критерий Х), а плохой отчего-то не признает индекс (в предикате критерий X появляется не сам по себе, а вместе с другими условиями, что приводит к TABLE ACCESS FULL). Статистики пересобирал с инвалидацией - результат нулевой. Что еще можно посмотреть, например в V$SQLAREA, чтобы понять, откуда/почему берется неправильный план и как заставить CBO взять правильный?
Ответ:
Задвинутый чайник
один и тот же запрос выполняю в SQL Plus (выполняется отлично!) и в моей программулине (выполняется плохо). В V$SQLAREA вижу два SQL_ID с разными планами выполнения.

Две строки в V$SQLAREA, два разных SQL_ID ==> два разных запроса.
Один запрос с несколькими планами - это одна строка в V$SQLAREA, один SQL_ID, несколько строк в V$SQL.
Вопрос: Планы выполнения запросов: предикаты (аргументы) в операторе Index Seek

Всем привет.

Есть простой теоретический вопрос по планам выполнения запросов. Почему-то не могу накопать на него ответ в мануалах / литературе, если кто-то, подскажет, где про этот момент написано или объяснит своими словами, - буду весьма признателен.

Вопрос в следующем. Есть простейший запрос, соединяющий две таблички (Employee и Address) внутренним соединением и выбирающий из них некоторое количество полей. Есть отбор по одному из полей таблицы Employee. Одна табличка без индексов вообще (Employee), другая (Address) содержит индекс по внешнем ключу, по которому идет соединение (индекс по полю EmployeeID).

SELECT employee.lastName, 
	   address.City
FROM   person.employee INNER JOIN person.address
	   ON employee.EmployeeID = address.EmployeeID
where employee.LastName = 'Иванов'



План запроса тоже простой. СУБД делает table scan по первой табличке по условию из отбора и index seek по второй (по ключу из первой таблицы), затем СУБД "добирает" результат с помощью RID Lookup и "собирает" все в кучу с помощью пары Nested Loops.

Интересует начало плана выполнения запроса - table scan первой таблицы и index seek по второй. Совсем точно - интересует index seek.

У него в аргументах (предикатах) написано следующее:

SEEK:([my_db].[Person].[Address].[EmployeeID]=[my_db].[Person].[Employee].[EmployeeID]) ORDERED FORWARD


В графическом плане выглядит примерно так же, только еще функция scalar operator добавляется после знака равенства.

При этом и в графическом, и в текстовом плане выполнения запроса table scan и index seek находится на одном уровне.

Что физически делает СУБД во время index seek? Все-таки использует ключи из оператора table scan и уже по ним делает поиск? Или просто получает все возможные ключи из первой таблицы и делает поиск по ним, а "отсекает" лишнее уже во время nested loops? Если первое - почему операции находятся на одном уровне в плане, ведь первая должна предшествовать второй, по идее?
Ответ: По моим наблюдения странное поведение планировщика происходит в первую очередь при изменении статистики. Выражается это в том что после пересчета с full scan и очистке хэша планов выполнения запросов ситуация меняется. Но также замечал что видимо сервер анализирует объем доступной(по сегментам) памяти. Выражалось это например при падении счетчика "время жизни страницы"(это скорее всего косвенный счетчик) оптимизатор без видимых причин начинал использовать преимущественно(на определенных типах запросов) нестед лупс вместо хэш джоина. Были мысли эту ситуацию смоделировать но как то лень. Да и главное как мы на это можем повлиять? Гарантированный способ - явно приклеивать xml плана выполнения. Если есть вырожденные случаи в селективности то явно в клиенте анализировать и подкладывать другой план. По моему опыту это не нужно для всех запросов , обычно их набирается 5-10ть на всю систему.
Вопрос: План выполнения запроса в MS Access

Подскажите, как получить план выполнения запроса в Access.

Нашел такой совет:
А как же в Access? Неужели разработчики не предусмотрели возможность просмотра плана выполнения запроса?

Оказалось такая возможность есть, просто она недокументированная. Если в разделе реестра
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Jet\4.0\Engines\Debug] создать строковый параметр JETSHOWPLAN и присвоить ему значение ON, то это заставит Access (после перезапуска) создавать текстовый файл showplan.out в папке Мои документы, в котором будет содержаться план выполнения запросов.
Построение плана выполнения запросов происходит в момент компиляции последних. Существующие запросы уже, как правило, скомпилированные. Чтобы заставить Access перекомпилировать запрос, нужно его изменить (как вариант открыть запрос, перейти в режим SQL и добавить пробел в конце), сохранить и выполнить.
Существует ли другая возможность, без использования реестра?

Раздела [...4.0/Jet] в [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\...] у меня нет.
Ответ: Нагуглила, что для Office 12 (Access 2007) правильное размещение ключа

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\12.0\Access Connectivity Engine\Engines\Debug]

Ветки Debug изначально нет, ее тоже нужно создать.

Сработало только после перезагрузки.

Добавлено через 11 минут
Мдя. Результат для Access 2007 совершенно не тот, какой ожидалось. Вот полное (с точностью до двух пустых строк, которые я удалила для экономии места форума) содержание файла showplan.out после открытия запроса в режиме конструктора, сохранения и выполнения:

---------------------------------------------
DATE: 0
VER: 12.00.6679

NOTE: Currently does not handle subqueries, vt parameters, and subqueries
NOTE: You may see ERROR messages in these cases

---
- Inputs to Query -
Table 'EventLine'
- End inputs to Query -

01) Sort table 'EventLine'
02) Insert into 'EventLine'
Т.е. ожидаемая информация об использовании индексов - отсуствует.

Добавлено через 39 минут
UPD: начало выводить информацию об индексах после сжатия базы данных.

Добавлено через 8 минут
UPD2: Окончательный вердикт: для адекватной работы плана выполнения запроса в Access 2007 нужно создать ключ в регистре, перезагрузить компьютер и сжать базу данных.
Вопрос: Разный план выполнения запроса.

Здравствуйте.
Есть сервер 1 (11.2.0.2) OS OEL 5.6
Есть сервер 2 (11.2.0.4) OS AIX 6.1
По характеристикам схожи.

На сервере 1 есть база данных, которая была экспортом/импортом перенесена на сервер 2.
Запрос:

select cut_id, substr(kato,1,2) ab,substr(kato,1,4) abcd,
decode(substr(kato,10,1),'1',1,'3',1,2) SPTM_CODE,
position,
count(fc.id) count_flat, count(distinct hc.house_cut_id) count_house,
sum(fc.quantityofinhabitants) resident_number, sum(fc.quantityofhouseholds) household_number,
sum(fc.living_square) living_square, sum(fc.full_square) full_square,
sum(hc.living_square) living_squareHouse, sum(hc.full_square) full_squareHouse
from SSR_DB31.flat_cut fc, SSR_DB31.house_cut hc,
(select position,id_class from SSR_DB31.accomplishment where nvl(id_class_parent,0)=0) ac
where fc.house_cut_id=hc.house_cut_id and hc.house_situation_id<>570
and substr(hc.house_accomplishment,position,1)='1'
group by cut_id, substr(kato,1,2),substr(kato,1,4),position,
decode(substr(kato,10,1),'1',1,'3',1,2)

выполняется на:
сервере 1 = 1.1 час
сервере 2 = 4.2 час

Один и тот же запрос показывает разные планы на серверах.
Также при инсерте Сервер 2 расходует больше темпового пространства и IO данных у него тоже больше.
Как быть?

К сообщению приложен файл. Размер - 125Kb
Ответ:
Perl'ун

Почему у тебя статистика в байтах отличается на базах? Что за хитрый экспорт-импорт? В select'е еще ладно. И то 10% уже сложно не заметить. А на INSERT одинаково байтов должно уходить, если данные одинаковые.


В актуальных должны быть, в estimated не обязаны - это всего лишь оценка.
Вопрос: План выполнения запроса: key lookup и clustered index seek

Добрый день.
Помогите, пожалуйста, с несколько нубским вопросом по планам выполнения запросов в MSSQL. Версия MSSQL - 2012.
Есть табличка с кластерным индексом по одному полю и некластерным индексом по другому.
Есть запрос, который делает отбор в секции WHERE по ключу некластерного индекса, и выводит в секции SELECT поле, которое отсутствует в некластерном индексе (т. е. СУБД нужно его вытаскивать из таблицы по ключу).
Графический план запрос показывает операцию Key Lookup (причем как физический, так и логический оператор оператора плана - Key Lookup).
Текстовый и XML планы запроса показывает операцию Clustered Index Seek (так же в виде физического и логического оператора).
В обоих случаях просматриваю фактические планы запросов (не estimated).
Почему так происходит? Ведь графический и текстовый / XML планы должны, по идее, показывать одинаковые данные? Или же дело в том, что Key Lookup и Clustered Index Seek - по сути, синониминые операторы, просто их в силу каких-то причин по-разному отображают в разных представлениях планов запросов?
Ответ: invm,

да, не докопал я до этой части документации.

Спасибо!
Вопрос: Прошу помочь прочитать план выполнения запроса

Добрый день, уважаемые форумчане!
Изучал примеры из топика опубликованного iap с примерами общих табличных выражений.
Решил вывести план выполенния запроса для примера №1 из данного топика.
DECLARE @Cardinality INT, @Seed INT, @Increment INT;[url=][/url]
SELECT @Cardinality = 10, @Seed = 5, @Increment = 3;
WITH T(ID,N) AS
(
 SELECT 1, @Seed WHERE @Cardinality >= 1
 UNION ALL
 SELECT ID + 1, N + @Increment FROM T WHERE ID < @Cardinality
)
SELECT ID, N FROM T ORDER BY ID
OPTION (MAXRECURSION 0);


Получил следующий план выполнения запроса:


в 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.4100.1" xmlns="http://schemas.microsoft.com/sqlserver/2004/07/showplan">
  <BatchSequence>
    <Batch>
      <Statements>
        <StmtSimple StatementCompId="2" StatementEstRows="4" StatementId="1" StatementOptmLevel="FULL" StatementOptmEarlyAbortReason="GoodEnoughPlanFound" CardinalityEstimationModelVersion="120" StatementSubTreeCost="0.0113838" StatementText="WITH T(ID,N) AS&#xD;&#xA;(&#xD;&#xA; SELECT 1, @Seed WHERE @Cardinality &gt;= 1&#xD;&#xA; UNION ALL&#xD;&#xA; SELECT ID + 1, N + @Increment FROM T WHERE ID &lt; @Cardinality&#xD;&#xA;)&#xD;&#xA;SELECT ID, N FROM T ORDER BY ID&#xD;&#xA;OPTION (MAXRECURSION 0)" StatementType="SELECT" QueryHash="0x8E689938FAFE6EF3" QueryPlanHash="0x5A68D2E5D4F49AA0" RetrievedFromCache="true">
          <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="1024" CachedPlanSize="24" CompileTime="0" CompileCPU="0" CompileMemory="224">
            <MemoryGrantInfo SerialRequiredMemory="512" SerialDesiredMemory="544" RequiredMemory="512" DesiredMemory="544" RequestedMemory="1024" GrantWaitTime="0" GrantedMemory="1024" MaxUsedMemory="16" />
            <OptimizerHardwareDependentProperties EstimatedAvailableMemoryGrant="208281" EstimatedPagesCached="104140" EstimatedAvailableDegreeOfParallelism="4" />
            <RelOp AvgRowSize="15" EstimateCPU="0.000112495" EstimateIO="0.0112613" EstimateRebinds="0" EstimateRewinds="0" EstimatedExecutionMode="Row" EstimateRows="4" LogicalOp="Sort" NodeId="0" Parallel="false" PhysicalOp="Sort" EstimatedTotalSubtreeCost="0.0113838">
              <OutputList>
                <ColumnReference Column="Recr1005" />
                <ColumnReference Column="Recr1006" />
              </OutputList>
              <MemoryFractions Input="1" Output="1" />
              <RunTimeInformation>
                <RunTimeCountersPerThread Thread="0" ActualRebinds="1" ActualRewinds="0" ActualRows="10" ActualEndOfScans="1" ActualExecutions="1" />
              </RunTimeInformation>
              <Sort Distinct="false">
                <OrderBy>
                  <OrderByColumn Ascending="true">
                    <ColumnReference Column="Recr1005" />
                  </OrderByColumn>
                </OrderBy>
                <RelOp AvgRowSize="15" EstimateCPU="1E-08" EstimateIO="0" EstimateRebinds="0" EstimateRewinds="0" EstimatedExecutionMode="Row" EstimateRows="4" LogicalOp="Lazy Spool" NodeId="1" Parallel="false" PhysicalOp="Index Spool" EstimatedTotalSubtreeCost="9.994E-06">
                  <OutputList>
                    <ColumnReference Column="Expr1010" />
                    <ColumnReference Column="Recr1005" />
                    <ColumnReference Column="Recr1006" />
                  </OutputList>
                  <RunTimeInformation>
                    <RunTimeCountersPerThread Thread="0" ActualRebinds="1" ActualRewinds="0" ActualRows="10" ActualEndOfScans="1" ActualExecutions="1" />
                  </RunTimeInformation>
                  <Spool Stack="true">
                    <RelOp AvgRowSize="15" EstimateCPU="2E-09" EstimateIO="0" EstimateRebinds="0" EstimateRewinds="0" EstimatedExecutionMode="Row" EstimateRows="4" LogicalOp="Concatenation" NodeId="2" Parallel="false" PhysicalOp="Concatenation" EstimatedTotalSubtreeCost="8.404E-06">
                      <OutputList>
                        <ColumnReference Column="Expr1010" />
                        <ColumnReference Column="Recr1005" />
                        <ColumnReference Column="Recr1006" />
                      </OutputList>
                      <RunTimeInformation>
                        <RunTimeCountersPerThread Thread="0" ActualRows="10" ActualEndOfScans="1" ActualExecutions="1" />
                      </RunTimeInformation>
                      <Concat>
                        <DefinedValues>
                          <DefinedValue>
                            <ColumnReference Column="Expr1010" />
                            <ColumnReference Column="Expr1007" />
                            <ColumnReference Column="Expr1009" />
                          </DefinedValue>
                          <DefinedValue>
                            <ColumnReference Column="Recr1005" />
                            <ColumnReference Column="Expr1000" />
                            <ColumnReference Column="Expr1003" />
                          </DefinedValue>
                          <DefinedValue>
                            <ColumnReference Column="Recr1006" />
                            <ColumnReference Column="@Seed" />
                            <ColumnReference Column="Expr1004" />
                          </DefinedValue>
                        </DefinedValues>
                        <RelOp AvgRowSize="15" EstimateCPU="2E-08" EstimateIO="0" EstimateRebinds="4" EstimateRewinds="0" EstimatedExecutionMode="Row" EstimateRows="1" LogicalOp="Compute Scalar" NodeId="3" Parallel="false" PhysicalOp="Compute Scalar" EstimatedTotalSubtreeCost="2E-08">
                          <OutputList>
                            <ColumnReference Column="Expr1007" />
                            <ColumnReference Column="Expr1000" />
                            <ColumnReference Column="@Seed" />
                          </OutputList>
                          <ComputeScalar>
                            <DefinedValues>
                              <DefinedValue>
                                <ColumnReference Column="Expr1007" />
                                <ScalarOperator ScalarString="(0)">
                                  <Const ConstValue="(0)" />
                                </ScalarOperator>
                              </DefinedValue>
                            </DefinedValues>
                            <RelOp AvgRowSize="11" EstimateCPU="1E-07" EstimateIO="0" EstimateRebinds="0" EstimateRewinds="0" EstimatedExecutionMode="Row" EstimateRows="1" LogicalOp="Compute Scalar" NodeId="4" Parallel="false" PhysicalOp="Compute Scalar" EstimatedTotalSubtreeCost="1.737E-06">
                              <OutputList>
                                <ColumnReference Column="Expr1000" />
                              </OutputList>
                              <ComputeScalar>
                                <DefinedValues>
                                  <DefinedValue>
                                    <ColumnReference Column="Expr1000" />
                                    <ScalarOperator ScalarString="(1)">
                                      <Const ConstValue="(1)" />
                                    </ScalarOperator>
                                  </DefinedValue>
                                </DefinedValues>
                                <RelOp AvgRowSize="9" EstimateCPU="4.8E-07" EstimateIO="0" EstimateRebinds="0" EstimateRewinds="0" EstimatedExecutionMode="Row" EstimateRows="1" LogicalOp="Filter" NodeId="5" Parallel="false" PhysicalOp="Filter" EstimatedTotalSubtreeCost="1.637E-06">
                                  <OutputList />
                                  <RunTimeInformation>
                                    <RunTimeCountersPerThread Thread="0" ActualRebinds="1" ActualRewinds="0" ActualRows="1" ActualEndOfScans="1" ActualExecutions="1" />
                                  </RunTimeInformation>
                                  <Filter StartupExpression="true">
                                    <RelOp AvgRowSize="9" EstimateCPU="1.157E-06" EstimateIO="0" EstimateRebinds="0" EstimateRewinds="0" EstimatedExecutionMode="Row" EstimateRows="1" LogicalOp="Constant Scan" NodeId="6" Parallel="false" PhysicalOp="Constant Scan" EstimatedTotalSubtreeCost="1.157E-06">
                                      <OutputList />
                                      <RunTimeInformation>
                                        <RunTimeCountersPerThread Thread="0" ActualRows="1" ActualEndOfScans="1" ActualExecutions="1" />
                                      </RunTimeInformation>
                                      <ConstantScan />
                                    </RelOp>
                                    <Predicate>
                                      <ScalarOperator ScalarString="[@Cardinality]&gt;=(1)">
                                        <Compare CompareOp="GE">
                                          <ScalarOperator>
                                            <Identifier>
                                              <ColumnReference Column="@Cardinality" />
                                            </Identifier>
                                          </ScalarOperator>
                                          <ScalarOperator>
                                            <Const ConstValue="(1)" />
                                          </ScalarOperator>
                                        </Compare>
                                      </ScalarOperator>
                                    </Predicate>
                                  </Filter>
                                </RelOp>
                              </ComputeScalar>
                            </RelOp>
                          </ComputeScalar>
                        </RelOp>
                        <RelOp AvgRowSize="15" EstimateCPU="1.68E-07" EstimateIO="0" EstimateRebinds="4" EstimateRewinds="0" EstimatedExecutionMode="Row" EstimateRows="4" LogicalOp="Inner Join" NodeId="14" Parallel="false" PhysicalOp="Nested Loops" EstimatedTotalSubtreeCost="6.665E-06">
                          <OutputList>
                            <ColumnReference Column="Expr1009" />
                            <ColumnReference Column="Expr1003" />
                            <ColumnReference Column="Expr1004" />
                          </OutputList>
                          <RunTimeInformation>
                            <RunTimeCountersPerThread Thread="0" ActualRows="9" ActualEndOfScans="1" ActualExecutions="1" />
                          </RunTimeInformation>
                          <NestedLoops Optimized="false">
                            <OuterReferences>
                              <ColumnReference Column="Expr1009" />
                              <ColumnReference Column="Recr1001" />
                              <ColumnReference Column="Recr1002" />
                            </OuterReferences>
                            <RelOp AvgRowSize="15" EstimateCPU="2E-08" EstimateIO="0" EstimateRebinds="4" EstimateRewinds="0" EstimatedExecutionMode="Row" EstimateRows="1" LogicalOp="Compute Scalar" NodeId="15" Parallel="false" PhysicalOp="Compute Scalar" EstimatedTotalSubtreeCost="2E-08">
                              <OutputList>
                                <ColumnReference Column="Expr1009" />
                                <ColumnReference Column="Recr1001" />
                                <ColumnReference Column="Recr1002" />
                              </OutputList>
                              <ComputeScalar>
                                <DefinedValues>
                                  <DefinedValue>
                                    <ColumnReference Column="Expr1009" />
                                    <ScalarOperator ScalarString="[Expr1008]+(1)">
                                      <Arithmetic Operation="ADD">
                                        <ScalarOperator>
                                          <Identifier>
                                            <ColumnReference Column="Expr1008" />
                                          </Identifier>
                                        </ScalarOperator>
                                        <ScalarOperator>
                                          <Const ConstValue="(1)" />
                                        </ScalarOperator>
                                      </Arithmetic>
                                    </ScalarOperator>
                                  </DefinedValue>
                                </DefinedValues>
                                <RelOp AvgRowSize="15" EstimateCPU="2E-08" EstimateIO="0" EstimateRebinds="4" EstimateRewinds="0" EstimatedExecutionMode="Row" EstimateRows="1" LogicalOp="Lazy Spool" NodeId="16" Parallel="false" PhysicalOp="Table Spool" EstimatedTotalSubtreeCost="2E-08">
                                  <OutputList>
                                    <ColumnReference Column="Expr1008" />
                                    <ColumnReference Column="Recr1001" />
                                    <ColumnReference Column="Recr1002" />
                                  </OutputList>
                                  <RunTimeInformation>
                                    <RunTimeCountersPerThread Thread="0" ActualRebinds="1" ActualRewinds="0" ActualRows="10" ActualEndOfScans="1" ActualExecutions="1" />
                                  </RunTimeInformation>
                                  <Spool Stack="true" PrimaryNodeId="1" />
                                </RelOp>
                              </ComputeScalar>
                            </RelOp>
                            <RelOp AvgRowSize="15" EstimateCPU="1E-07" EstimateIO="0" EstimateRebinds="3" EstimateRewinds="0" EstimatedExecutionMode="Row" EstimateRows="1" LogicalOp="Compute Scalar" NodeId="20" Parallel="false" PhysicalOp="Compute Scalar" EstimatedTotalSubtreeCost="6.477E-06">
                              <OutputList>
                                <ColumnReference Column="Expr1003" />
                                <ColumnReference Column="Expr1004" />
                              </OutputList>
                              <ComputeScalar>
                                <DefinedValues>
                                  <DefinedValue>
                                    <ColumnReference Column="Expr1003" />
                                    <ScalarOperator ScalarString="[Recr1001]+(1)">
                                      <Arithmetic Operation="ADD">
                                        <ScalarOperator>
                                          <Identifier>
                                            <ColumnReference Column="Recr1001" />
                                          </Identifier>
                                        </ScalarOperator>
                                        <ScalarOperator>
                                          <Const ConstValue="(1)" />
                                        </ScalarOperator>
                                      </Arithmetic>
                                    </ScalarOperator>
                                  </DefinedValue>
                                  <DefinedValue>
                                    <ColumnReference Column="Expr1004" />
                                    <ScalarOperator ScalarString="[Recr1002]+[@Increment]">
                                      <Arithmetic Operation="ADD">
                                        <ScalarOperator>
                                          <Identifier>
                                            <ColumnReference Column="Recr1002" />
                                          </Identifier>
                                        </ScalarOperator>
                                        <ScalarOperator>
                                          <Identifier>
                                            <ColumnReference Column="@Increment" />
                                          </Identifier>
                                        </ScalarOperator>
                                      </Arithmetic>
                                    </ScalarOperator>
                                  </DefinedValue>
                                </DefinedValues>
                                <RelOp AvgRowSize="9" EstimateCPU="4.8E-07" EstimateIO="0" EstimateRebinds="3" EstimateRewinds="0" EstimatedExecutionMode="Row" EstimateRows="1" LogicalOp="Filter" NodeId="21" Parallel="false" PhysicalOp="Filter" EstimatedTotalSubtreeCost="6.077E-06">
                                  <OutputList />
                                  <RunTimeInformation>
                                    <RunTimeCountersPerThread Thread="0" ActualRebinds="10" ActualRewinds="0" ActualRows="9" ActualEndOfScans="10" ActualExecutions="10" />
                                  </RunTimeInformation>
                                  <Filter StartupExpression="true">
                                    <RelOp AvgRowSize="9" EstimateCPU="1.157E-06" EstimateIO="0" EstimateRebinds="0" EstimateRewinds="3" EstimatedExecutionMode="Row" EstimateRows="1" LogicalOp="Constant Scan" NodeId="22" Parallel="false" PhysicalOp="Constant Scan" EstimatedTotalSubtreeCost="4.157E-06">
                                      <OutputList />
                                      <RunTimeInformation>
                                        <RunTimeCountersPerThread Thread="0" ActualRows="9" ActualEndOfScans="9" ActualExecutions="9" />
                                      </RunTimeInformation>
                                      <ConstantScan />
                                    </RelOp>
                                    <Predicate>
                                      <ScalarOperator ScalarString="[Recr1001]&lt;[@Cardinality]">
                                        <Compare CompareOp="LT">
                                          <ScalarOperator>
                                            <Identifier>
                                              <ColumnReference Column="Recr1001" />
                                            </Identifier>
                                          </ScalarOperator>
                                          <ScalarOperator>
                                            <Identifier>
                                              <ColumnReference Column="@Cardinality" />
                                            </Identifier>
                                          </ScalarOperator>
                                        </Compare>
                                      </ScalarOperator>
                                    </Predicate>
                                  </Filter>
                                </RelOp>
                              </ComputeScalar>
                            </RelOp>
                          </NestedLoops>
                        </RelOp>
                      </Concat>
                    </RelOp>
                  </Spool>
                </RelOp>
              </Sort>
            </RelOp>
            <ParameterList>
              <ColumnReference Column="@Increment" ParameterRuntimeValue="(3)" />
              <ColumnReference Column="@Seed" ParameterRuntimeValue="(5)" />
              <ColumnReference Column="@Cardinality" ParameterRuntimeValue="(10)" />
            </ParameterList>
          </QueryPlan>
        </StmtSimple>
      </Statements>
    </Batch>
  </BatchSequence>
</ShowPlanXML>


Не могли бы вы помочь мне разобрать данный план выполнения:
Пытался сам, но смущает два момента и от них идет непонимание.
перввый момент Table Spool - как данный оператор используется
и второй момент оператор Table Spool, зависит от оператора Index spool, а оператор Index Spool находится после оператора объединяющего данные.....

К сообщению приложен файл. Размер - 75Kb
Ответ: Спасибо
Вопрос: Разная скорость выполнения запроса

Есть таблица tab1. В ней несколько полей. Поля id_user number(7), id_tovar number(5), nomer_tovar number(2) составляют индекс.

Есть процедура form_tab1. Она формирует таблицу tab1. На входе id_user, id_tovar, nomer_tovar.
Мой id_user = 1.
У пользователя id_user=2.
Запускаем процедуру form_tab1(1, 1 , 1) и для пользователя form_tab1(2, 1 , 1). В итоге получаем 800 строк в таблице: 400 строк с id_user=1 и 400 строк с id_user=2. Поля для id_user=1 и id_user=2 совершенно одинаковые: по 400 одинаковых строк.

Далее 2 запроса. В запросах объединяются 6 таблиц, среди них есть таблица tab1. Таблицы соединяются по ключам. Оба запроса возвращают по 400 строк. Их отличает только поле id_user. В запросах ничего необычного, простое объединение таблиц. Разве что 2 таблицы объединяются с помощью full join.

Разница вот в чём: запрос с id_user=1 работает полторы секунды. А запрос с id_user=2 работает полторы минуты! Почему такая разница?? Ведь данные в таблицах одинаковы! Запросы одинаковые! Всё одинаково, кроме времени выполнения запросов.

Где рыть? С индексом что-то не то? Как определить проблему?

Использую SQL Developer. Запустил SQL Plain (по F10). Стал смотреть coast (советовали обратить на них внимание). Но косты с моим id_user имеют даже меньшее значение, чем с тем id_user, запрос с которым выполняется дольше!

Помогите советом, я не сис админ, поэтому прошу вас поподробнее что и куда
Ответ: Ответ был на этот вопрос
автор
Запрос с использованием try2date у пользователя usr1 не включает индексы ни при каких условиях. А у пользователя usr2 включает.

По try2date написали выше.
Вопрос: Странности с планом выполнения запроса на секционированной таблице

... точнее с его отображением.

Преамбула:
Имеется Microsoft SQL Server 2014 (SP2-CU1) (KB3178925) - 12.0.5511.0 (X64)
Aug 19 2016 14:32:30
Copyright (c) Microsoft Corporation
Enterprise Edition (64-bit) on Windows NT 6.3 <X64> (Build 9600: ) (Hypervisor)
Имеется секционированная таблица-хранилище.

При попытке отобразить эстимейтед план запроса к хранилищу, причем запрос полностью укладывается в некий индекс, оптимизатор выдает предупреждение, что "хорошо бы использовать такой-то покрывающий индекс".
Причем индекс именно с такими параметрами на таблице есть. И именно он в плане запроса отображается.

Если добавить к запросу Option (recompile), то отображается точно такой же план (с точно таким же предполагаемым количеством строк и, на первый взгляд, теми же операциями на тех же индексах), но уже без зеленой подсказки "создайте индекс".

Выполняются запросы и вроде бы одинаково.

В чем может быть дело???

На таблице есть множество индексов, но все они выровнены по партициям, и для них указано STATISTICS_INCREMENTAL=ON, в т.ч. для кластерного индекса.
При подгрузке данных в хранилище данные сначала грузятся в таблицу-близнец с той же структурой индексов (но отключенных).
Потом индексы включаются (Alter index All REBUILD), потом делается swap partition, потом уже в целевой таблице на соответствующей партиции делается UPDATE STATISTICS WITH RESAMPLE для каждой инкрементальной статистики (и для индексов, и для созданных вручную статистик по полям).
Автообновление и автосоздание статистик отключено.

Чувствую, засада именно в этом.

Что я мог упустить, не подскажите?
Ответ: uaggster,

Не за что. Я и не думал, что планы одинаковые (у вас они отличаются хотя бы предложением индекса, что говорит о том, что они прошли разный путь оптимизации). Вполне понятно, что планы могут отличаться, есть такая штука как Parameter Embedding Optimization, посмотрите вот :
автор
In SQL Server 2008 RTM we introduced behaviour that allowed potentially better plans to be created when using the OPTION RECOMPILE syntax. The way this worked in principal was that if the OPTION RECOMPILE syntax was used, SQL could assume that the plan for the statement in question would not need to re-used, since it was always going to recompile. Therefore the query optimizer could safely use the actual parameter values passed to the statement when choosing a plan, as opposed to just using a parameterised template. In certain circumstances this can lead to dramatic performance gains, especially when you have parameter values which vary wildly and need different plans dependent upon the values passed.

У вас ведь вопрос был о том, почему выдается предупреждение по индексу, а не о разных планах, поэтому суть ответа в том, что если такой индекс есть и успешно используется, то на предупреждение можно не обращать внимания.
Вопрос: разные планы выполнения на боевой и развернутой тестовой бд. причины?

пока нашел только одно отличие:
в самой бд:
на боевой базе:
LC_COLLATE = 'ru_RU.UTF-8'
LC_CTYPE = 'ru_RU.UTF-8'
на тестовой
LC_COLLATE = 'en_US.UTF-8'
LC_CTYPE = 'en_US.UTF-8'

все остальное совпадает. физически на разных машинах, оперативы намного больше на боевом.

в запросе какрас идет сравнение построчное
...
from Wperson0 n0
	inner join Wperson1 n1 on 
		n0.firstname = n1.firstname  
		and n0.middlename=n1.middlename
		and lower(n0.secondname)=lower(n1.secondname) 
...

на боевом значения берутся по индексу
на тестовом идет прямое обращение к бд=(

может быть причина разных планов в LC_COLLATE, LC_CTYPE или еще искать причины?
Ответ: на тесте, т.к. 9.4. можно пофантазировать сюда:
+
with
Wperson0 as ( -- ФИО взятое из документа (в одном доке участвует два участника)
	with Wdoc as (SELECT * FROM (select distinct unnest(ARRAY[80404130,80404134]) as person_id ) foo LIMIT 2 -- всегда не больше 2 ? -- так и скажите планёру
		)
	--select distinct np.firstname, np.middlename, np.secondname, np.birth_date from Wdoc doc inner join ibd.person np on np.person_id = doc.person_id
	SELECT DISTINCT --только если оба дока -- одна морда лица
		np.firstname, np.middlename, np.secondname, np.birth_date from Wdoc doc
	FROM Wdoc
	,LATERAL (SELECT np.firstname, np.middlename, np.secondname, np.birth_date from ibd.person np WHERE np.person_id = doc.person_id 
		ORDER BY np.person_id LIMIT 1) np -- навязываем однократный seek по каждому person_id из 2-х
	),

Wperson1 as ( -- все совпадения ФИО + дата, дата может быть не указана
	select /*distinct*/ np.person_id -- сдаётся -- это pk
	from Wperson0 np0 
	inner join
	FROM ibd.person np on 
		np0.firstname = np.firstname and 
		np0.middlename=np.middlename and 
		lower(np0.secondname)=lower(np.secondname) and 
		--coalesce(np0.birth_date,np.birth_date,'1000-10-10')=coalesce(np.birth_date,np0.birth_date,'1000-10-10')) -- за такое -- убивать
		AND ((np0.birth_date = np.birth_date) OR (np0.birth_date IS NULL AND np.birth_date IS NULL))
		-- какие тут есть [составные/ф-ые]индексы ? -- вот тут можно немного покопаться
	)
select * from Wperson1


и вообще -- любовь к дистинктам на мильонных табличках -- это что-то.

в бою, к сожалению, "лейтерал" не скажешь
Вопрос: вопрос по плану выполнения

Всем добрый вечер
Пытаюсь разобраться в плане выполнения запросов.
Есть запрос к тестовой базе AdventureWorks, Таблице Person.Addresses
Текст запроса:
select AddressID from Person.Address where City='Snohomish'
 and 
SYSTEM_USER='sa'



Хотел посмотреть как будет строиться план выполнения
если добавить "внешнее условие" не связанное с таблицей
получил вот такой план выполнения :

  |--Nested Loops(Inner Join, OUTER REFERENCES:([AdventureWorks].[Person].[Address].[AddressID]))
       |--Filter(WHERE:(STARTUP EXPR(suser_sname()=CONVERT_IMPLICIT(nvarchar(4000),[@2],0))))
       |    |--Index Scan(OBJECT:([AdventureWorks].[Person].[Address].[IX_Address_StateProvinceID]))
       |--Clustered Index Seek(OBJECT:([AdventureWorks].[Person].[Address].[PK_Address_AddressID]), SEEK:([AdventureWorks].[Person].[Address].[AddressID]=[AdventureWorks].[Person].[Address].[AddressID]),  WHERE:([AdventureWorks].[Person].[Address].[City]=N'Snohomish') LOOKUP ORDERED FORWARD)


В связи с этим возник вопрос: зачем производится сканирование некластерного индекса
почему не используется кластерный индекс
Ответ: не знаю, сойдет ли как доказательство "туфтовости" плана NL + IX_Address_StateProvinceID,
но предлагаю такой эксперимент:
выбираем ВСЕ поля Person.Address без всяких условий.
что в плане? очевидный скан всей таблицы, что же еще.
а теперь добавим проверку логина.
и уж тут тоже всего 2 варианта: все или ничего.

а теперь объявляю конкурс на лучшее оправдание появления в плане NL.
какой еще NL, если мне все равно нужна вся таблица (ну или не нужна)???
но как же, снова в плане NL + IX_Address_StateProvinceID.

предлагаю даже первое правдоподобное предположение:
в заведомо невыполняемом плане всегда будет красоваться NL + самый узкий индекс.
этакая видимость проделанной работы: "я честно поискал самый узкий индекс"
(предположение не мое, автор может забрать себе приз, если других предложений не будет)