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);
Как повторить?
- Применить скрипт к базе данных.
- Войти в БД с консоли
~$ psql -U username -W db_name
. - Запустить функцию
SELECT do_cache_test();
(желательно несколько раз) - Получить данные. (Тут красиво не получилось)
Данные хранятся в микросекундах, поэтому делим на 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';
- Записать все в блокнотик. Построить график в 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 |
*Время - среднее
График:
- Google sheet
- Код можно посмотреть здесь: github gist