Все технические форумы на одном сайте Удобный поиск информации с популярных форумов в одном месте
Вопрос: Производительность вставки

Привет всем!
У нас с 2-м подрядчиком на проекте возник спор по поводу производительности разных способов вставки больших данных в таблицу.
Есть тип:
CREATE OR REPLACE TYPE num_tab AS TABLE OF NUMBER;

Есть процедура, которая принимает себе на вход некий ИД и данный тип:
PROCEDURE test(p_id NUMBER, p_nested_ids num_tab);


Способ вставки № 1:
FORALL i IN p_nested_ids.first .. p_nested_ids.last
  INSERT INTO test_table
    (id, nested_id)
  VALUES
    (p_id, p_nested_ids(i));

Способ вставки № 2:
INSERT INTO test_table(id, nested_id)
SELECT p_id, column_value
FROM TABLE(p_nested_ids);


Пытался найти сравнение в гугле - нашел много сравнений между FOR и FORALL, а по теме - ничего.
Помогите разобраться, что в действительности быстрее выходит, и почему.
Спасибо ;-)
Ответ: Kumotori,

Спасибо
Вопрос: Производительность и транзакции в Cache и GlobalsDb (java globals API)

Добрый день.

Пишу приложение, работающее с обеими СУБД с использованием java globals API (http://docs.intersystems.com/cache20131/csp/docbook/DocBook.UI.Page.cls?KEY=BXJV_globals#BXJV_globals_transact_transact ). У меня есть два потока выполняющих вставку данных. До данного момента вставлял данные с помощью connection.createNodeReference и далее node.appendSubscript и node.set. Насколько тяжеловесна операция createNodeReference? Могу ли я для вставки новой записи каждый раз ее вызывать? И я так понимаю, что данные на диск записываются после вызова node.close, это так? Дело в том, что мой код мог отработать, я даже закрыл программу, а диск может еще скрипеть секунд двадцать. Что в этот момент происходит?

Фактически приложение выполняет массовую вставку записей постоянно. В реляционных СУБД при вставке большого количества записей важно делать это пачками в рамках одной транзакции (например, одна транзакция на 1000 вставок). С java globals API та же ситуация? Если да, то как запускать разные транзакции из разных потоков? Судя по документации соединение разделяется между потоками.

И еще вопрос. Есть ли серьезная деградация производительности вставки при накоплении в одном из узлов нескольких сотен тысяч или миллионов узлов?
Ответ: servit, спасибо за ответы!
Вопрос: вставка большого количества строк в таблицу

Ребята, требуется вставить порядка 100 тысяч строк (считанных из файла) в таблице, способом оптимальным по производительности. К примеру есть таблица ФИО, и файл на 100 тысяч фио. В таблице и в файле могут быть дубликаты. Чем воспользоваться чтобы можно было быстро вставить в таблице массив прочитанных из файла фио исключая дублирование?

По задаче необходимо выполнить все в виде запросов/запроса.
Ответ: а чем лучше вставлять большие таблицы размером 60 столбцов на 1 млн.строк? BULK INSERT или BCP ? Где лучше отслеживать ошибки при вставке (импорте)?
Вопрос: Java и производительность

Интересует мнение по востребованности производительности в рамках среды обитания Java. Подразумевается, конечно же, не оптимизации запросов на стороне БД и всяческая работа с файлами да сетями, которая опять же оптимизируется вне JVM. Но интересно понять, на сколько востребована производительность именно внутри JVM, без внешних систем.

Смысл вопроса в понимании места этой технологии. Она позволяет повышать производительность ряда алгоритмов в разы, но, естественно, не без некоторых затрат на изучение предмета. По сути это упрощение связывания Java с низкоуровневым программированием. То есть оставаясь в рамках одной и той же IDE, можно писать оптимизированное до самого железа ПО.

Итак, какие встречавшиеся в вашем жизненном опыте системы упирались в производительность процессора, загружаемого именно JVM, но не сторонними системами ? На сколько простым выглядит создание конвертера из объектной модели в загружающем процессор алгоритме в набор массивов ? Массивы - это наиболее удобный способ достижения производительности на низком уровне. В них можно трансформировать всяческие структуры со ссылками друг на друга, просто заменив объекты на набор последовательно расположенных значений полей, а ссылки - на индексы в массиве. В общем - нужна ли производительность для Java и велика ли для неё цена в виде освоения системы команд процессора и написания конвертера объекты-массивы и обратно ?
Ответ:
Leonid Kudryavtsev
alex55555
...Если процессор загружен на 100% именно Java, то значит надо что-то думать в сторону оптимизации. И один из вариантов - сделать код умнее, чем способен JIT....

На корявом средстве по Вашей ссылки Вы способны это сделать? "сделать код умнее, чем способен JIT" ?

Почитайте о средстве по ссылке, там на простом ангельском языке весьма доходчиво показано, что JIT отстаёт от ручного кода в 5 раз. Не на проценты, обратите внимание, но в разы. Так что ваши сомнения как бы со всею очевидностью показывают ваше ... Уж сори за почти прямым текстом вдоль неприятного места.
Leonid Kudryavtsev
Теоретически, JIT, может генерировать код значительно более эффективный чем традиционные компиляторы ... На практике, IMHO пока отстает.

Все компиляторы пока ещё слабоваты. Хотя возможность сделать их значительно умнее вполне имеется. Но пока умнее их не сделали, можно повысить производительность софта на Java при помощи указанного по ссылке подхода. При этом повышение возможно в разы. А уж на десятки процентов - это уж точно применимо к любой Java программе, загружающей процессор на 100%.
Вопрос: IO производительность MS SQL Server

Есть несколько MS SQL серверов под базы данных, используемые для MS CRM Dynamics.
Анализ производительности счетчиков performance monitor показывает вполне приемлемые значения, субъективно производительность тоже вполне приемлемая.
Но, при этом все файлы баз данных и логи лежат на одном логическом диске.
Темпдб и все системные базы вообще лежат на системном диске, что уже совсем плохо.
Я несколько раз рекомендовал разнести файлы, но владелец говорит, что дисковая подсистема это некий SAN на аутсорсинге и аутсорсинг настраивает SAN так, что проблем нет.
И проблем действительно пока нет, вопрос, нужно ли все таки настаивать на разнесении хотя бы файлов логов и баз данных и перенесении темпдб на несистемный диск.
Ответ:
alister
Я несколько раз рекомендовал разнести файлы, но владелец говорит, что дисковая подсистема это некий SAN на аутсорсинге и аутсорсинг настраивает SAN так, что проблем нет.
И проблем действительно пока нет, вопрос, нужно ли все таки настаивать на разнесении хотя бы файлов логов и баз данных и перенесении темпдб на несистемный диск.
Ваш вопрос фактически в том, кто отвечает за производительность, за администрирование сервера СУБД.

Если аутсорсинг настраивает SAN не "в общем", а для ваших систем, если там есть квалифицированные DBA, то они сами должны мониторить ситуацию, настраивать свой SAN правильно (например, выделяя разные шпиндели под разные типы нагрузки).
И должны отвечать за принимаемые ими решения.

Если аутсорсинг SAN устраняется от настройки для ваших систем, настраивает "сферический массив в вакуме", который будет хорош только в их любимом синтетическом тесте, а на вопросы MSSQL работает медленно будут отвечать, что "M$ мастдай переходите на убунту", то могут быть проблемы.

Вот этих случаях вы не должны отвечать за производительность, нужно, что бы "владелец" это понимал.

То есть нужно до него донести, что он может вас вынудить принять формальную ответственность, что он может выместить на вас зло лишением премии, но принимать технические решения и соответственно нести фактическую ответственность всё равно будет "аутсорсинг SAN".

Или вы сами несёте ответственность, но при этом сотрудничаете с "аутсорсингом SAN", работаете с ними в тесном контакте.
То есть они для вас должны быть консультантами и специалистами по собственно хранилищу, а вот как его лучше использовать для MSSQL, как проводить тесты производительности, должны решать вы.
Вопрос: насколько бэкап tempdb влияет на производительность СУБД в целом

Админы уверяют нас, что бэкап tempdb в рабочее время не будет сильно влиять на производительность работы самой СУБД с другими базами данных. Время бэкапа примерно 3 часа
Вопрос к опытным админам: так ли это? Понятно, что все зависит он нагрузки, кол-ва и качества запросов и т.д. Если упадет производительность, то примерно на сколько %.
Ответ:
abort
да там очень много много пакетов. 3 часа - это максимальное время. Если будет делаться диффер бэкап базы db1 с 9:00 до 13:00, насколько может упасть производительность СУБД в работе с другими базами данных на этом же инстансе. Одни говорят, что производительность упадет на 90%, другие что будет почти незаметно
Бакапы никак не конфликтуют с запросами любых типов к базе.

Однако, бакап потребляет ресурсы (дисковые). Если нагрузка на диски большая, то бакап отберёт часть пропускной способности дисков.
Посмотреть это можно по дисковой очереди, и следить за "временем отклика" во время бакапа. Это можно смотреть по счётчикам производительности, или в перфмониторе.
То есть если у вас к диску постояно очередь из ещё не обработанных команд, то понятно, что добавление дополнительных команд от бакапа к этой очереди не ускорит выполнение команд от рабочей нагрузки.
Поэтому и стараются делать бакапы в период наименьшей нагрузки.

Безусловно, на 90% снижения не будет, но оно может быть заметное. ИМХО я бы оценил так: от 0% до 30%.
Вопрос: дают ли разные аналитические функции разную производительность

oracle 11.2 EE
есть таблица, содержащая бухгалтерские полупроводки.
каждая строка содержит остаток перед проводкой C_START_SUM и сумму проводки C_SUMMA
задача: собрать итоги: оборот за день и остаток на конец дня по каждому счету.

текущее решение - наглядное (на каждом уровне запроса можно визуально выполнить отладку) - через row_number:

--уровень 3 - вычисляем итого оборот за день / остаток на конец дня
          select account_id, 
          trunc(c_date) c_date, 
          sum(C_TURNOVER_DBT) C_TURNOVER_DBT, 
          sum(C_TURNOVER_DBT_LCL) C_TURNOVER_DBT_LCL,
          sum(C_TURNOVER_CRT) C_TURNOVER_CRT, 
          sum(C_TURNOVER_CRT_LCL) C_TURNOVER_CRT_LCL,
          sum(C_BALANCE) C_BALANCE, 
          sum(C_BALANCE_LCL) C_BALANCE_LCL
          from (
              select  r2.*,
              --уровень 2 - для последней строки вычисляем баланс
              --баланс считаем только для последней записи во избежание размножения при SUM() на уровне выше:
               case when rn = 1 then nvl(C_START_SUM,0) +     direction * nvl(C_SUMMA,0)     end as C_BALANCE,
               case when rn = 1 then nvl(C_START_SUM_NAT,0) + direction * nvl(C_SUMMA_NAT,0) end as C_BALANCE_LCL
                    from (
                    select /*+ full(r) full(r.t) full(r.t.DA) full(r.t.DC) PARALLEL(16) */
                           r.*
                           --уровень 1 - нумеруем строки
                          ,row_number() over (partition by r.account_id, trunc(r.c_date) order by r.c_date desc, r.id desc) as rn --последняя запись на ключе Счет+Опердень
                           case when C_DT = '1' then -1 else 1 end direction --множитель для остатка 
                    from recs r --полупроводки
                    where r.c_date >= date '2015-01-04' and r.c_date <date '2015-01-04' +1 
                    ) r2
              ) r3
          group by account_id,trunc(c_date)

понятно, что такое решение не единственное - как минимум напрашиваются:
а) max() keep dense_rank last over (partition by
б) Last_value() over (partition by


вопросы:

1) что можете предложить эффективнее (править таблицу-источник или предрассчитать что-то нельзя)

2) есть ли смысл выписывать варианты а и б для сравнения производительности, или производительность будет варьироваться в пределах погрешности измерения?
или так: дают ли разные аналитические функции реально разную производительность?

спасибо!
Ответ: по существу темы - дают ли разные аналитические функции разную производительность - тестированием получена информация, что lag(с кляузой ignore nulls) из-за ignore nulls дает сильную просадку производительности (запрос уходит в несколько часов раздумий), и решение на нем можно/нужно заменять другими аналит.функциями (в данном случае на last_value с той же кляузой ignore nulls - что из часов ожидания делает минуты) - подробнее тут
Вопрос: Мониторинг производительности

Здравствуйте.

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

Хотелось бы получить совет от знающих или ткнуть меня ссылкой.

- какой софт лучше (и/или необходимо) использовать для мониторинг и настройки производительности инстанции сервера, расположенного на Windows хосте?
- какой софт лучше (и/или необходимо) использовать для мониторинг и настройки производительности инстанции сервера, расположенного на Linux хосте?
- tсть ли что-то более-менее универсальное, или стоит использовать разный софт или же стоит переехать на Linux полностью?

Большое спасибо!
Ответ:
ОКТОГЕН
Для анализа производительности можно использовать анализатор логов pgfouine.

Я думаю, что лучше pgbadger — он давно перерос pgfouine.
Вопрос: Секционирование и падение производительности

Подскажите, кто-нибудь сталкивался с падением производительности при различной реализации секционирования для не кластерных индексов?

Нужны примеры, статьи, чтобы не наступить на грабли.

Могу привести свой пример, когда производительность скорее всего упадет из-за spill в tempdb.

Например, если у нас есть секционированный некластерный ключ по полю datetime, то в запросе вида:
  declare @d datetime = getdate() 

  SELECT *
  FROM [MY].[dbo].[TBL]
  where datetime > @d
  order by datetime desc

Будет давать sort после index seek по каждой из секций:
  |--Sort(ORDER BY:([Database3].[dbo].[TBL].[datetime] DESC))
       |--Index Seek(OBJECT:([Database3].[dbo].[TBL].[idx_datetime]), SEEK:([PtnId1000] >= (1) AND [PtnId1000] <= (3) AND [Database3].[dbo].[TBL].[datetime] > [@d]) ORDERED FORWARD)


При этом аналогичный не секционированный индекс будет работать без сортировки.

Вот пример создания и заполнения самой таблицы и схемы:
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE PARTITION FUNCTION [Fn_part](smallint) AS RANGE LEFT FOR VALUES (0, 100)
GO
CREATE PARTITION SCHEME [Schem_part] AS PARTITION [Fn_part] TO ([PRIMARY], [PRIMARY], [PRIMARY])
GO



CREATE TABLE [dbo].[TBL](
	[id] [smallint] NOT NULL,
	[datetime] [datetime] NOT NULL,
 CONSTRAINT [PK_b_old] PRIMARY KEY CLUSTERED 
(
	[id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
) on Schem_part(id)

CREATE NONCLUSTERED INDEX [idx_datetime] ON [dbo].[TBL]
(
	[datetime] ASC
)
INCLUDE ( 	[id]) 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  Schem_part(id)
GO

GO


insert into dbo.[TBL]
select top 50 row_number() over (order by name) - 50, dateadd(day, row_number() over (order by name) - 50, getdate()) from master.sys.objects as o
union all
select top 50 row_number() over (order by name), dateadd(day, row_number() over (order by name), getdate()) from master.sys.objects as o
union all
select top 50 row_number() over (order by name) + 50, dateadd(day, row_number() over (order by name) + 50, getdate()) from master.sys.objects as o
union all
select top 50 row_number() over (order by name) + 100, dateadd(day, row_number() over (order by name) + 100, getdate()) from master.sys.objects as o
Ответ: Mind,

> Еще одна жертва мифа о том что секционирование это решение для производительности?

ну ИНОГДА же - улучшает :D очень иногда, но все же
а так - согласен, конечно же. секции - хорошо для админов. и, часто, боль для разрабов
Вопрос: Postgres 9.5:"INSERT INTO ... ON CONFLICT" - Как понять произошла вставка или обновление?

Postgres 9.5
Как в конструкции
   INSERT INTO table (Id, Name)
        VALUES (:in_Id, :in_Name)
   ON CONFLICT (Id)
            DO             
        UPDATE 
           SET name = :in_name


понять какая операция была выполнена - вставка или обновление?

В Firebird в аналогичной конструкции "UPDATE OR INSERT" это достигается так:
   UPDATE OR INSERT INTO table (Id, Name) VALUES (:in_Id, :in_Name) RETURNING OLD.Id


т.е можно указать префикс перед возвращаемым PK: если он NULL, то произошла вставка...

А как получить информацию о том была вставка или обновление в Postgres?
Ответ: shaposh,

можно решить эту проблему путём использования системной невидимой колонки xmax



тест
CREATE TABLE account
(
  id bigserial,
  name varchar,
  surname varchar,
  address varchar,
  PRIMARY KEY (id),
  CONSTRAINT unique_person UNIQUE (name, surname, address)
);

INSERT INTO account as a (id, name, surname, address)
VALUES (1, 'Вася', 'Пупкин', 'Москва, Кремль')
ON CONFLICT (id)
DO UPDATE SET
name=EXCLUDED.name || ' (бывший ' || a.name || ')',
surname=EXCLUDED.surname || ' (бывший ' || a.surname || ')'
returning xmax, * ;

xmax	id	name	surname	address
0	1	Вася	Пупкин	Москва, Кремль

INSERT INTO account AS a (id, name, surname, address)
VALUES (1, 'Петя', 'Петров', 'Москва, Кремль')
ON CONFLICT (id)
DO UPDATE SET
name=EXCLUDED.name || ' (бывший ' || a.name || ')',
surname=EXCLUDED.surname || ' (бывший ' || a.surname || ')'
returning xmax, * ;

xmax	       id	name	                        surname	                        address
22087375	1	Петя (бывший Вася)	Петров (бывший Пупкин)	Москва, Кремль


т.е.
0 - выполнена вставка
не 0 - выполнен update