режим отложенного обновления sybase ase - PullRequest
0 голосов
/ 29 июня 2018

Я мог бы использовать некоторую помощь относительно выбора оптимизатора для обновления ниже. Я ожидал прямого обновления, а не отложенного обновления.

В реальной жизни это касается целевой таблицы, содержащей ~ 5M строк, обновляемых из меньшей таблицы с ~ 200k строками. Отложенное обновление занимает некоторое время, в том числе из-за того, что в целевой таблице около 60 столбцов.

Любые предложения, объясняющие это поведение, очень приветствуются, включая предложения по улучшению производительности этого запроса. Таблицу меньшего размера можно легко изменить, изменения в целевой таблице оказывают большее влияние, поскольку она является частью модели данных продукта.

Большое спасибо!

Elroy

select @@version --Adaptive Server Enterprise/15.5/EBF 18158 SMP ESD#2/P/X64/Windows Server/asear155/2514/64-bit/OPT/Wed Aug 25 05:39:57 2010

IF OBJECT_ID('test_target') IS NOT NULL
DROP TABLE test_target
GO
CREATE TABLE test_target  ( 
    id              numeric(15,0) IDENTITY NOT NULL,
    col1            numeric(15,0) NOT NULL,
    col2            char(15) NOT NULL,
CONSTRAINT PK_test_target PRIMARY KEY CLUSTERED(id)
    )
LOCK DATAPAGES
go
insert into test_target select 1, '123'
insert into test_target select 1, '456'
go

IF OBJECT_ID('test_from') IS NOT NULL
DROP TABLE test_from
GO
CREATE TABLE test_from  ( 
    from_id         numeric(15,0) NOT NULL,
    from_col2    char(15) NOT NULL
    )
LOCK ALLPAGES
GO
insert into test_from select 1,'1'
go
create unique clustered index k1 on test_from (from_id)
go

set showplan on
go

update test_target 
set col2 = from_col2
from test_target
join test_from on from_id = id 

set showplan off
go

QUERY PLAN FOR STATEMENT 1 (at line 1).


 STEP 1
     The type of query is UPDATE.

   4 operator(s) under root

     |ROOT:EMIT Operator (VA = 4)
     |
     |   |UPDATE Operator (VA = 3)
     |   |  The update mode is deferred.
     |   |
     |   |   |NESTED LOOP JOIN Operator (VA = 2) (Join Type: Inner Join)
     |   |   |
     |   |   |   |SCAN Operator (VA = 0)
     |   |   |   |  FROM TABLE
     |   |   |   |  test_from
     |   |   |   |  Table Scan.
     |   |   |   |  Forward Scan.
     |   |   |   |  Positioning at start of table.
     |   |   |   |  Using I/O Size 16 Kbytes for data pages.
     |   |   |   |  With LRU Buffer Replacement Strategy for data pages.
     |   |   |
     |   |   |   |SCAN Operator (VA = 1)
     |   |   |   |  FROM TABLE
     |   |   |   |  test_target
     |   |   |   |  Using Clustered Index.
     |   |   |   |  Index : PK_test_target
     |   |   |   |  Forward Scan.
     |   |   |   |  Positioning by key.
     |   |   |   |  Keys are:
     |   |   |   |    id ASC
     |   |   |   |  Using I/O Size 16 Kbytes for index leaf pages.
     |   |   |   |  With LRU Buffer Replacement Strategy for index leaf pages.
     |   |   |   |  Using I/O Size 16 Kbytes for data pages.
     |   |   |   |  With LRU Buffer Replacement Strategy for data pages.
     |   |
     |   |  TO TABLE
     |   |  test_target
     |   |  Using I/O Size 16 Kbytes for data pages.

Ответы [ 2 ]

0 голосов
/ 13 июля 2018

Если есть награда за «худший ответ», вы можете вручить ее мне. Я работал в Sybase старшим консультантом и пришел к выводу, что прямое обновление не стоит времени, чтобы оно заработало. Если вас беспокоит производительность, я бы предложил использовать приложение или хранимую процедуру для выполнения обновления в пакетном режиме. Поместите ID в таблицу источника обновлений и обновите, где ID от 1 до 5000, от 2 до 5001 и т. Д. Мой личный опыт показывает, что это дает вам лучший результат.

Кроме того, вы проверили правила для прямого обновления? Они слабее, чем были в мое время, когда любой обновляемый столбец NULL или переменного размера (varchar) делал обновление отложенным, но все еще довольно ограничительным: http://infocenter.sybase.com/help/index.jsp?topic=/com.sybase.infocenter.dc00743.1502/html/queryprocessing/queryprocessing29.htm.

Я новичок здесь - это должно было быть отправлено по-другому, так как это на самом деле не запрошенное решение?

0 голосов
/ 29 июня 2018

Вообще говоря, чтобы получить direct обновление, необходимо, чтобы обновляемая таблица была на первом месте в плане запросов ... хотя, в идеале, в этом случае оптимизатор должен быть в состоянии выяснить, что а) вы ' повторное объединение таблиц на основе 2 уникальных индексов (т. е. гарантированное совпадение 1: 1), поэтому b) обновление direct было бы предпочтительным.

Существует несколько способов получить direct обновление ... и при условии, что вы не хотите заключать запрос в пару команд set forceplan on/off и не хотите добавлять абстрактный план запроса (AQP - подсказки оптимизатора), вы можете попробовать что-то вроде:

-- for test purposes, make sure optimizer isn't re-using query plan from previous test run
set statement_cache off
go

set showplan on
go

update test_target

                 -- push the join into a sub-query
set    tt.col2 = (select tf1.from_col2 from test_from tf1 where tf1.from_id = tt.id)

from   test_target tt

where  -- only process tt rows that have a match in tf2
       exists(select 1 from test_from tf2 where tf2.from_id = tt.id)
go

STEP 1
    The type of query is UPDATE.

    8 operator(s) under root

   |ROOT:EMIT Operator (VA = 8)
   |
   |   |UPDATE Operator (VA = 7)
   |   |  The update mode is direct.
   |   |
   |   |   |SQFILTER Operator (VA = 6) has 2 children.
   |   |   |
   |   |   |   |NESTED LOOP JOIN Operator (VA = 3) (Join Type: Inner Join)
   |   |   |   |
   |   |   |   |   |GROUP SORTED Operator (VA = 1)
   |   |   |   |   |Distinct
   |   |   |   |   |
   |   |   |   |   |   |SCAN Operator (VA = 0)
   |   |   |   |   |   |  FROM TABLE
   |   |   |   |   |   |  test_from
   |   |   |   |   |   |  tf2
   |   |   |   |   |   |  Table Scan.
   |   |   |   |   |   |  Forward Scan.
   |   |   |   |   |   |  Positioning at start of table.
   |   |   |   |   |   |  Using I/O Size 2 Kbytes for data pages.
   |   |   |   |   |   |  With LRU Buffer Replacement Strategy for data pages.
   |   |   |   |
   |   |   |   |   |SCAN Operator (VA = 2)
   |   |   |   |   |  FROM TABLE
   |   |   |   |   |  test_target
   |   |   |   |   |  tt
   |   |   |   |   |  Using Clustered Index.
   |   |   |   |   |  Index : PK_test_target
   |   |   |   |   |  Forward Scan.
   |   |   |   |   |  Positioning by key.
   |   |   |   |   |  Keys are:
   |   |   |   |   |    id ASC
   |   |   |   |   |  Using I/O Size 2 Kbytes for index leaf pages.
   |   |   |   |   |  With LRU Buffer Replacement Strategy for index leaf pages.
   |   |   |   |   |  Using I/O Size 2 Kbytes for data pages.
   |   |   |   |   |  With LRU Buffer Replacement Strategy for data pages.
   |   |   |
   |   |   |  Run subquery 1 (at nesting level 1).
   |   |   |
   |   |   |  QUERY PLAN FOR SUBQUERY 1 (at nesting level 1 and at line 11).
   |   |   |
   |   |   |   Correlated Subquery.
   |   |   |   Subquery under an EXPRESSION predicate.
   |   |   |
   |   |   |   |SCALAR AGGREGATE Operator (VA = 5)
   |   |   |   |  Evaluate Ungrouped ONCE AGGREGATE.
   |   |   |   |
   |   |   |   |   |SCAN Operator (VA = 4)
   |   |   |   |   |  FROM TABLE
   |   |   |   |   |  test_from
   |   |   |   |   |  tf1
   |   |   |   |   |  Using Clustered Index.
   |   |   |   |   |  Index : k1
   |   |   |   |   |  Forward Scan.
   |   |   |   |   |  Positioning by key.
   |   |   |   |   |  Keys are:
   |   |   |   |   |    from_id ASC
   |   |   |   |   |  Using I/O Size 2 Kbytes for data pages.
   |   |   |   |   |  With LRU Buffer Replacement Strategy for data pages.
   |   |   |
   |   |   |  END OF QUERY PLAN FOR SUBQUERY 1.
   |   |
   |   |  TO TABLE
   |   |  test_target
   |   |  Using I/O Size 2 Kbytes for data pages.

Будет ли это лучше / быстрее, чем отложенное обновление, будет зависеть от объема строк, которые должны быть отсканированы с tt плюс количество соединений с tf1 и tf2.

Также имейте в виду, что никакие хитрости не помогут, если у вас есть триггер на столе или вы обновляете индексированный столбец.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...