Nano Hash - криптовалюты, майнинг, программирование

Заявление о медленном обновлении

мы имеем дело с очень медленным оператором обновления в проекте Oracle.

Вот небольшой скрипт для повторения проблемы:

drop table j_test;

CREATE TABLE J_TEST
(
  ID  NUMBER(10) PRIMARY KEY,
  C1   VARCHAR2(50 BYTE),
  C2   VARCHAR2(250 BYTE),
  C3   NUMBER(5),
  C4   NUMBER(10)
);

-- just insert a bunch of rows
insert into j_test (id)
select rownum 
from <dummy_table>
where rownum < 100000;

-- this is the statement that runs forever (longer than my patience allows)
update j_test
set C3 = 1,
    C1 = 'NEU';    

В некоторых средах оператор Update-Statement занимает всего около 20 секунд, а в других оператор выполняется несколько минут. При использовании большего количества строк проблема становится еще хуже.

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

Любые идеи и предложения? Спасибо, Торстен.

17.11.2008

  • C4 NUMBER(10) по сравнению с SET C4 = 'NEU' заставляет меня почесать голову. Это намерение, или я упускаю захватывающую функцию Oracle? 17.11.2008
  • Пожалуйста, не обновляйте каждую строку. Сделайте это через CTAS (Создать таблицу как выбранную) - см. ниже. 18.11.2008
  • Извините, ребята, надеюсь, я устранил этот глюк. 19.11.2008

Ответы:


1

Одной из возможных причин низкой производительности является цепочка строк. Все ваши строки изначально имеют столбцы C3 и C4 null, а затем вы обновляете их все, чтобы они имели значение. Новые данные не помещаются в существующие блоки, поэтому Oracle приходится связывать строки с новыми блоками.

Если вы заранее знаете, что будете это делать, вы можете предварительно выделить достаточно свободного места следующим образом:

CREATE TABLE J_TEST
(
  ID  NUMBER(10) PRIMARY KEY,
  C1   VARCHAR2(50 BYTE),
  C2   VARCHAR2(250 BYTE),
  C3   NUMBER(5),
  C4   NUMBER(10)
) PCTFREE 40;

... где PCTFREE указывает процент свободного места для обновлений. Значение по умолчанию — 10, чего недостаточно для этого примера, где строки более или менее удваиваются в размере (от средней длины от 8 до 16 байтов в соответствии с моей базой данных).

Этот тест показывает разницу:

SQL> CREATE TABLE J_TEST
  2  (
  3    ID  NUMBER(10) PRIMARY KEY,
  4    C1   VARCHAR2(50 BYTE),
  5    C2   VARCHAR2(250 BYTE),
  6    C3   NUMBER(5),
  7    C4   NUMBER(10)
  8  );

Table created.

SQL> insert into j_test (id)
  2  select rownum 
  3  from transactions
  4  where rownum < 100000;

99999 rows created.

SQL> update j_test
  2  set C3 = 1,
  3      C2 = 'NEU'
  4  /

99999 rows updated.

Elapsed: 00:01:41.60

SQL> analyze table j_test compute statistics;

Table analyzed.

SQL> select blocks, chain_cnt from user_tables where table_name='J_TEST';

    BLOCKS  CHAIN_CNT
---------- ----------
       694      82034

SQL> drop table j_test;

Table dropped.

SQL> CREATE TABLE J_TEST
  2  (
  3    ID  NUMBER(10) PRIMARY KEY,
  4    C1   VARCHAR2(50 BYTE),
  5    C2   VARCHAR2(250 BYTE),
  6    C3   NUMBER(5),
  7    C4   NUMBER(10)
  8  ) PCTFREE 40;

Table created.

SQL> insert into j_test (id)
  2  select rownum 
  3  from transactions
  4  where rownum < 100000;

99999 rows created.

SQL> update j_test
  2  set C3 = 1,
  3      C2 = 'NEU'
  4  /

99999 rows updated.

Elapsed: 00:00:27.74

SQL> analyze table j_test compute statistics;

Table analyzed.

SQL> select blocks, chain_cnt from user_tables where table_name='J_TEST';

    BLOCKS  CHAIN_CNT
---------- ----------
       232          0

Как видите, с PCTFREE 40 обновление занимает 27 секунд вместо 81 секунды, а результирующая таблица использует 232 блока без связанных строк вместо 694 блоков с 82034 связанными строками!

17.11.2008
  • Хорошая демонстрация, но рекомендация обновить 100 % строк — это просто реализация плохих идей. 17.11.2008
  • Марк, я предположил, что это надуманный пример, а настоящие обновления приходят позже по каким-то деловым причинам. Очевидно, что если строки должны сразу иметь эти значения, то они должны быть вставлены вместе с ними! 18.11.2008

  • 2

    Попробуй это:

    insert into j_test (id, C3, C4)
    select rownum, 1, 'NEU'
    from <dummy_table>
    where rownum < 100000;
    
    17.11.2008

    3

    Вы действительно пытаетесь обновить числовое поле C4 NUMBER (10) со значением символа «NEU»?

    Предположим, вы пытаетесь сделать следующее:

    UPDATE j_test
       SET c3 = 3
     WHERE c1 = 'NEU'
    

    Возможно, вам потребуется создать индекс в поле поиска и проанализировать таблицу, чтобы ускорить процесс обновления. Если вы действительно пытаетесь обновить всю таблицу, скорость обновления может отличаться. Это зависит от памяти, скорости доступа к диску, создания журналов повторов и т. д.

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

    17.11.2008

    4

    Вы уверены, что проблема не в том, что вы вставляете «NEU» в поле «Число (10)»? Он выполняет преобразование «на лету» из «NEU» в число (??) перед вставкой.

    Я имею в виду серьезно, другие ответы - хорошая и полезная информация, но 100 тыс. строк при полном обновлении должны быть быстрыми.

    Помните - индексы, как правило, ускоряют выборку и замедляют вставку/обновление.

    17.11.2008

    5

    Это очень похоже на вопрос и мой ответ здесь.

    Никогда не обновляйте 100% строк в таблице. Просто следуйте процедуре по этой ссылке. создайте «правильный ответ» в виде новой таблицы, а затем замените эту новую таблицу на старую. То же самое с удалением большого процента строк. Просто гораздо эффективнее использовать описанный мной сценарий.

    РЕДАКТИРОВАТЬ: Если кому-то из вас это кажется плохой идеей, просто знайте, что это метод, рекомендованный Томом Китом.

    17.11.2008

    6

    Другая возможность состоит в том, что одно UPDATE ожидает, потому что таблица заблокирована (например, в таблице есть еще одно незафиксированное UPDATE)
    Эта ссылка содержит оператор SQL для отображения блокировок

    17.11.2008
    Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

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

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..