PostgreSQL Sequence chache test - Timur00Kh/KHAFIZYANOV_11_702 GitHub Wiki

  • Задача: сравнить скорость вставки элементов в таблицы, на которые наложен SEQUENCE c кэшем и без. (Количество входных данных: 1000, 5000, 7500, 10000)
  • Проблема: каждый раз вставка выполнялась с разным временем. Порой вставка меньшего кол-ва данных занимала больше времени, чем вставка большего количества.
  • Решение: выполнить тест несколько раз и почитать среднее значение. Однако делать это в ручную слишком долго, поэтому я решил написать функцию, которая сделает это за меня. И заодно лучше познакомиться с синтаксисом SQL.

Дисклеймер: Делал просто по фану. Возможно все костыльно(так и есть).


Сначала пытался разобраться с массивами и строками в SQL. Но так и не понял как это работает. (не смог даже массив перебрать). Документация у Постгреса довольно объемная, так что найти ответ на вопрос не так легко.

  • Один из вариантов функции, которая, конечно же, не работает:
create function tt()
  returns time[]
language plpgsql
as $$
DECLARE
  i INT;
  j INT;
	time TIME;
  us_arr time[4];
  vals integer[];
	BEGIN

  i := 0;
  time := clock_timestamp();
  WHILE i < 10 LOOP
    j := 0;
    time := clock_timestamp();
    WHILE j < 1000 LOOP
      INSERT INTO dog (name) VALUES ('somename');
      j := j + 1;
    end loop;
    time := clock_timestamp() - time;
    us_arr[i][0] = us_arr[i][0] + time;
    i := i + 1;
  end loop;

  RETURN us_arr;
	END;
$$;

Как замерять?

Выбрал такой способ:

timer := clock_timestamp();
/* INSERT */
timer := clock_timestamp() - timer;

Где хранить?

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

CREATE TABLE time_keeper (
  type VARCHAR(10),
  microisecs INT
);

/* Вставка данных */
i := extract(microseconds from timer) :: int;
INSERT INTO time_keeper VALUES ('1000', i);

Как повторить?

  1. Применить скрипт к базе данных.
  2. Войти в БД с консоли ~$ psql -U username -W db_name.
  3. Запустить функцию SELECT do_cache_test(); (желательно несколько раз)
  4. Получить данные. (Тут красиво не получилось)

Данные хранятся в микросекундах, поэтому делим на 1000, чтобы получить в ms.

/*Команда для получения среднего времени вставки 1000 элементов без кэша*/
SELECT avg(microisecs) / 1000 AS test1000 FROM time_keeper WHERE type = '1000';

/*Команда для получения среднего времени вставки 1000 элементов c кэшем 1000*/
SELECT avg(microisecs) / 1000 AS cache1000 FROM time_keeper WHERE type = 'c1000';

/*Команда для получения среднего времени вставки 5000 элементов без кэша*/
SELECT avg(microisecs) / 1000 AS test5000 FROM time_keeper WHERE type = '5000';

/*Команда для получения среднего времени вставки 5000 элементов c кэшем 5000*/
SELECT avg(microisecs) / 1000 AS cache5000 FROM time_keeper WHERE type = 'c5000';

/*Команда для получения среднего времени вставки 7500 элементов без кэша*/
SELECT avg(microisecs) / 1000 AS test7500 FROM time_keeper WHERE type = '7500';

/*Команда для получения среднего времени вставки 7500 элементов c кэшем 7500*/
SELECT avg(microisecs) / 1000 AS cache7500 FROM time_keeper WHERE type = 'c7500';

/*Команда для получения среднего времени вставки 10000 элементов без кэша*/
SELECT avg(microisecs) / 1000 AS test10000 FROM time_keeper WHERE type = '10000';

/*Команда для получения среднего времени вставки 10000 элементов c кэшем 10000*/
SELECT avg(microisecs) / 1000 AS cache10000 FROM time_keeper WHERE type = 'c10000';
  1. Записать все в блокнотик. Построить график в Exel.

Для удаления всех таблиц, функций и всего-всего: SELECT delete_cache_test();

Итог.

Кол-во тестов: 53

Mode \ Insert amount 1000 5000 7500 10000
Usual 74.48 ms 106.77 ms 168.21 ms 213.93 ms
Cache 19.40 ms 76.26 ms 104.48 ms 191.44 ms

*Время - среднее

График:

Graph