Upload
devday
View
618
Download
5
Embed Size (px)
DESCRIPTION
Даниил Каменский — ведущий специалист проектов SQLinfo.ru (http://sqlinfo.ru/) и Webew.ru (http://webew.ru/), архитектор баз данных в компании ЦВТ. Даниил на Моем Круге: http://kamenskiydaniil.moikrug.ru/. Расширенный SQL в MySQL и PostgreSQL. Сравнение возможностей Расширение SQL: — пользовательские переменные; — оконные функции; — рекурсивный обход деревьев; — расширения ANSI SQL для работы с таблицами. Особенности и отличия базовых функций в MySQL и PostgreSQL: — типы таблиц особенности физического размещения; — работа с индексами; — оптимизация подзапросов; — трудности перевода: примеры.
Citation preview
Расширенный SQL в MySQL и PostgreSQL. Сравнение возможностей.
Даниил Каменский[email protected]
2
План доклада
Расширения SQL пользовательские переменные оконные функции рекурсивные запросы расширения для работы с таблицами
3
План доклада
Особенности и отличия базовых функций в MySQL и PostgreSQL
типы таблиц, особенности физического размещения
работа с индексами оптимизация подзапросов дополнительно
4
Польз. переменные MySQL
Поддерживаются с версии 3.23.6 Возможность присваивать значения и
использовать далее в рамках сессииSELECT @min_price:=MIN(`price`) FROM
`shop`;SELECT * FROM `shop` WHERE
`price`=@min_price;
5
Пример №1: Пики загрузки
Поиск максимального различия между смежными значениями
6
Структура таблицы
7
Без явной сортировки
ALTER table `t` ORDER BY `t` ASC;SET @data=NULL,@max=0; SELECT
@max:=if(v-@data>@max,v-data,@max),@data:=v
FROM `t`; SELECT @max;
8
Сортировка индексом
CREATE INDEX t_v ON t(t, v);SET @data=NULL,@max=0; SELECT
@max:=if(v-@data>@max,v-data,@max),@data:=v
FROM `t` FORCE INDEX (t_v); SELECT @max;
9
Сортировка в запросе
SET @data=NULL,@max=0; SELECT
@max:=if(v-@data>@max,v-data,@max),@data:=v
FROM (SELECT * FROM `t` ORDER BY t); SELECT @max;
10
Аналог в модели РБД
SELECT MAX(t1.v - (
SELECT v FROM t t2 WHERE t2.t < t1.t ORDER BY t2.t DESC LIMIT 1)
) FROM t t1;
11
Пример №2
Оценка загрузки каналов связи за определенные временные промежутки
12
Реализация через ПП
select @c:=0; select t, v from (
select t, if (t % 5, @c := @c+v, @c := v) as v, if( (t + 1) % 5,1,0) as mark from t) tt
where mark = 0;select sum(v) from t group by (t-(second(t)%5));
13
Детализация запроса
14
Длительности выполнения
15
Пример №3
Поиск n элементов группы по критерию. CREATE TABLE salary (
dep_id int, --идентификатор отделаemp_id int, --идентификатор работникаsal int -- зарплата
);
16
Запрос через ПП
set @n=2, @i=0, @p=0; SELECT * FROM
(SELECT * FROM `salary` ORDER BY dep_id ASC, sal DESC) t
WHERE if (@p=dep_id, @i:=@i+1,(@i:=0) or (@p:=dep_id))
AND @i<@n;
17
Аналог в РБД
SELECT t1.* FROM salary t1 HAVING ((SELECT count(*) FROM `salary` t2 WHERE t2.dep_id=t1.dep_id AND
t2.sal>t1.sal) <2) ORDER BY dep_id, sal DESC;
18
SWAP колонок, rownum
UPDATE t SET field1=field2, field2=field1Неправильный результат!set @tmp='';UPDATE t SET field1=(@tmp:=field1),
field1=field2, field2=@tmp;
SET @n:=0;SELECT @n:=@n+1 AS rownum, t.* FROM t;
19
Оконные функции PostgreSQL
Выполнение вычисления над списком строк в таблице, которые так или иначе относятся к текущей строке
Вычисление агрегатного значения без использования GROUP BY
20
Примеры функций
lag() – предыдущее значение в разбиении
row_number() – номер строки в разбиении
first_value() – первое значение в разбиении
21
Оконные функции
SELECT dep_id, emp_id, sal, 100 * sal::float/ (sum(sal) OVER (PARTITION BY dep_id))
FROM salaryWHERE dep_id = 1;
22
Макс. перепад через ПП
В postgresql.confcustom_variable_classes = 'lv'
select set_config ('lv.data', ‘0', true);select set_config ('lv.max_value', '0', true);select current_setting('lv.data')::integer
23
Макс. перепад через ОФ
SELECT max(v) FROM (SELECT p.v - lag(t.v) OVER (ORDER BY t) as v FROM t) tt;
24
Макс. перепад через функцию
create function public.temp_func() returns int as $$DECLARE prev integer; curr integer; max_ integer;BEGIN max_ := 0; prev := 0;FOR curr IN SELECT v FROM pp LOOPif (curr - prev > max_) then max_ := curr - prev;
end if;prev := curr; END LOOP;return max_; END $$ language plpgsql;
25
Скорости выполнения запросов в PostgreSQL
Таблица на 10,000,000 записейОконные функции: 2,5 cекПользовательские переменные: 13 секФункция на plpgsql: 2 секЗапрос с подзапросами: 20 сек
26
Элементы групп через ОФ
SELECT dep_id, emp_id, sal FROM (SELECT
row_number() OVER (partition BY dep_id ORDER BY sal desc ) num,dep_id, emp_id, sal
FROM salary ) t
WHERE num < 3;
27
Рекурсивные запросы
with [recursive] <имя_алиаса_запроса> [ (<список столбцов>) ]as (<запрос>)<основной запрос>
28
Дерево, структура
29
Обход дерева в ширину
WITH RECURSIVE recursetree(val, id, level, pathstr) AS ( SELECT val, id, 0, cast('' as text) FROM tree WHERE
parent_id = 0 UNION ALL SELECT t.val, t.id, rt.level + 1, rt.pathstr || '=>' || t.val::text FROM tree t JOIN recursetree rt ON rt.id = t.parent_id )
SELECT space(level) || val, id, level, pathstr FROM recursetree ORDER BY level, id;
30
Вывод рекурсивного запроса
31
Intersect
SELECT t1.val FROM set_operations_1 t1 INTERSECT SELECT t2.val FROM set_operations_2 t2;
SELECT val FROM set_operations_1 WHERE val IN (SELECT val FROM set_operations_2);
SELECT t1.val FROM set_operations_1 t1 JOIN set_operations_2 t2 using(val);
32
Except
SELECT t1.val FROM set_operations_1 t1 EXCEPT SELECT t2.val FROM set_operations_2 t2;
SELECT val FROM set_operations_1 WHERE val NOT IN (SELECT val FROM set_operations_2);
SELECT t1.val FROM set_operations_1 t1 LEFT JOIN set_operations_2 t2 USING (val) WHERE t2.val IS NULL
33
34
Работа с таблицами
ON DUPLICATE KEYinsert into param(param, val)
values(‘project_version’,100) on duplicate key update val=‘100';
REPLACE INTOreplace into param(param, val) values(‘project_version’, ‘100’);
35
Работа с таблицами
INSERT IGNOREinsert ignore into param(param, val)
values(‘project_version’,100) insert into param(param, val) select 'project_version', ‘100' where 1 not in
(select 1 from param where param = 'project_version');
36
Реализация upsert в PG
CREATE OR REPLACE FUNCTION upsert(id_ integer, val_ integer) RETURNS void AS
$$
BEGIN
LOOP
UPDATE t SET val = val_ WHERE id = id_
IF found THEN RETURN; END IF; BEGIN
INSERT INTO t(id, val) VALUES (id_, val_); RETURN;
EXCEPTION WHEN unique_violation THEN
END;
END LOOP;
END; $$ LANGUAGE 'plpgsql';
37
Создание правила
CREATE RULE "t_on_duplicate_ignore" AS ON INSERT TO "t"
WHERE EXISTS(SELECT 1 FROM y WHERE pk_col = NEW.pk_col_1)
DO INSTEAD NOTHING;
38
Типы таблиц в MySQL
InnoDBMyISAMMemoryMergeArchiveBlackhole
39
Типы таблиц в MySQL
tmp_table_size
max_heap_table_size
innodb_table_per_file
40
Индексы
Основные типыBtreeHashMySQL – только memory-таблицыPostgreSQL – hash не рекомендуется
41
Индексные алгоритмы
MySQL: Невозможность использовать составные индексы при нестрогом равенстве в начале
SELECT * FROM t WHERE a<3 AND b<5;Директива USE/IGNORE/FORCE INDEXPostgreSQL: Невозможность указать индекс
явно.Возможность регуляции черезset enable_***scan=1 и set enable_***scan=0
42
Алгоритмы JOIN
MySQL: nested loopPostgreSQL:nested loop joinmerge joinhash join
43
Функц. и сост. индексы
CREATE INDEX i ON billing(is_payed) WHERE is_payed = false;
CREATE INDEX i ON users ( substr(email, strrevpos(email , '.') + 1 ));CREATE INDEX i ON y(f1 ASC, f2 DESC);
44
MySQL - подзапросы
SELECT * FROM users WHERE id IN (SELECT poster_id FROM posts WHERE
poster_ip LIKE ‘212.194.55.%’);
SELECT * FROM users u JOIN posts p ON u.id=p.poster_id WHERE p.poster_ip LIKE ‘212.194.55.% ’;
45
Анонимные блоки кода
MySQL: CREATE/DROP IF EXISTS/IF NOT EXISTSPostgreSQL:DO $$ beginif exists (select 1 from pg_tables where tablename =
‘t') then drop table t;end if; end $$;
46
Дополнение
MySQL:Фальшивые Foreign Keys у таблиц MyISAMФальшивые hash-индексы у таблиц не memoryПри @@sql_mode <> ‘ANSI’ возможность делать ошибки
– например SELECT avg(a), b FROM t;PostgreSQL: Отсутствие возможности менять колонки местами Генерация исключений в хранимых процедурах
47
Спасибо за внимание!
48
Планы исполнения запросов
А.Запрос с ППСинтаксический анализ запросаСоздание плана исполненияОпределение хранилища базы (engine)Цикл foreach { Обращение к engine }Б.Цикл внутри ХП { Синтаксический анализ запроса (курсор) Определение хранилища базы (engine) Обращение к engine Переход к следующему шагу цикла (интерпретатор языка SQL)}