sql-ник devday. Каменский. Расширенный sql в mysql и postgresql....

48
Расширенный SQL в MySQL и PostgreSQL. Сравнение возможностей. Даниил Каменский [email protected]

Upload: devday

Post on 25-Jan-2015

616 views

Category:

Documents


5 download

DESCRIPTION

Даниил Каменский — ведущий специалист проектов SQLinfo.ru (http://sqlinfo.ru/) и Webew.ru (http://webew.ru/), архитектор баз данных в компании ЦВТ. Даниил на Моем Круге: http://kamenskiydaniil.moikrug.ru/. Расширенный SQL в MySQL и PostgreSQL. Сравнение возможностей Расширение SQL: — пользовательские переменные; — оконные функции; — рекурсивный обход деревьев; — расширения ANSI SQL для работы с таблицами. Особенности и отличия базовых функций в MySQL и PostgreSQL: — типы таблиц особенности физического размещения; — работа с индексами; — оптимизация подзапросов; — трудности перевода: примеры.

TRANSCRIPT

Page 1: SQL-ник DevDay. Каменский. Расширенный SQL в MySQL и PostgreSQL. Сравнение возможностей

Расширенный SQL в MySQL и PostgreSQL. Сравнение возможностей.

Даниил Каменский[email protected]

Page 2: SQL-ник DevDay. Каменский. Расширенный SQL в MySQL и PostgreSQL. Сравнение возможностей

2

План доклада

Расширения SQL пользовательские переменные оконные функции рекурсивные запросы расширения для работы с таблицами

Page 3: SQL-ник DevDay. Каменский. Расширенный SQL в MySQL и PostgreSQL. Сравнение возможностей

3

План доклада

Особенности и отличия базовых функций в MySQL и PostgreSQL

типы таблиц, особенности физического размещения

работа с индексами оптимизация подзапросов дополнительно

Page 4: SQL-ник DevDay. Каменский. Расширенный SQL в MySQL и PostgreSQL. Сравнение возможностей

4

Польз. переменные MySQL

Поддерживаются с версии 3.23.6 Возможность присваивать значения и

использовать далее в рамках сессииSELECT @min_price:=MIN(`price`) FROM

`shop`;SELECT * FROM `shop` WHERE

`price`=@min_price;

Page 5: SQL-ник DevDay. Каменский. Расширенный SQL в MySQL и PostgreSQL. Сравнение возможностей

5

Пример №1: Пики загрузки

Поиск максимального различия между смежными значениями

Page 6: SQL-ник DevDay. Каменский. Расширенный SQL в MySQL и PostgreSQL. Сравнение возможностей

6

Структура таблицы

Page 7: SQL-ник DevDay. Каменский. Расширенный SQL в MySQL и PostgreSQL. Сравнение возможностей

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;

Page 8: SQL-ник DevDay. Каменский. Расширенный SQL в MySQL и PostgreSQL. Сравнение возможностей

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;

Page 9: SQL-ник DevDay. Каменский. Расширенный SQL в MySQL и PostgreSQL. Сравнение возможностей

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;

Page 10: SQL-ник DevDay. Каменский. Расширенный SQL в MySQL и PostgreSQL. Сравнение возможностей

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;

Page 11: SQL-ник DevDay. Каменский. Расширенный SQL в MySQL и PostgreSQL. Сравнение возможностей

11

Пример №2

Оценка загрузки каналов связи за определенные временные промежутки

Page 12: SQL-ник DevDay. Каменский. Расширенный SQL в MySQL и PostgreSQL. Сравнение возможностей

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));

Page 13: SQL-ник DevDay. Каменский. Расширенный SQL в MySQL и PostgreSQL. Сравнение возможностей

13

Детализация запроса

Page 14: SQL-ник DevDay. Каменский. Расширенный SQL в MySQL и PostgreSQL. Сравнение возможностей

14

Длительности выполнения

Page 15: SQL-ник DevDay. Каменский. Расширенный SQL в MySQL и PostgreSQL. Сравнение возможностей

15

Пример №3

Поиск n элементов группы по критерию. CREATE TABLE salary (

dep_id int, --идентификатор отделаemp_id int, --идентификатор работникаsal int -- зарплата

);

Page 16: SQL-ник DevDay. Каменский. Расширенный SQL в MySQL и PostgreSQL. Сравнение возможностей

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;

Page 17: SQL-ник DevDay. Каменский. Расширенный SQL в MySQL и PostgreSQL. Сравнение возможностей

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;

Page 18: SQL-ник DevDay. Каменский. Расширенный SQL в MySQL и PostgreSQL. Сравнение возможностей

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;

Page 19: SQL-ник DevDay. Каменский. Расширенный SQL в MySQL и PostgreSQL. Сравнение возможностей

19

Оконные функции PostgreSQL

Выполнение вычисления над списком строк в таблице, которые так или иначе относятся к текущей строке

Вычисление агрегатного значения без использования GROUP BY

Page 20: SQL-ник DevDay. Каменский. Расширенный SQL в MySQL и PostgreSQL. Сравнение возможностей

20

Примеры функций

lag() – предыдущее значение в разбиении

row_number() – номер строки в разбиении

first_value() – первое значение в разбиении

Page 21: SQL-ник DevDay. Каменский. Расширенный SQL в MySQL и PostgreSQL. Сравнение возможностей

21

Оконные функции

SELECT dep_id, emp_id, sal, 100 * sal::float/ (sum(sal) OVER (PARTITION BY dep_id))

FROM salaryWHERE dep_id = 1;

Page 22: SQL-ник DevDay. Каменский. Расширенный SQL в MySQL и PostgreSQL. Сравнение возможностей

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

Page 23: SQL-ник DevDay. Каменский. Расширенный SQL в MySQL и PostgreSQL. Сравнение возможностей

23

Макс. перепад через ОФ

SELECT max(v) FROM (SELECT p.v - lag(t.v) OVER (ORDER BY t) as v FROM t) tt;

Page 24: SQL-ник DevDay. Каменский. Расширенный SQL в MySQL и PostgreSQL. Сравнение возможностей

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;

Page 25: SQL-ник DevDay. Каменский. Расширенный SQL в MySQL и PostgreSQL. Сравнение возможностей

25

Скорости выполнения запросов в PostgreSQL

Таблица на 10,000,000 записейОконные функции: 2,5 cекПользовательские переменные: 13 секФункция на plpgsql: 2 секЗапрос с подзапросами: 20 сек

Page 26: SQL-ник DevDay. Каменский. Расширенный SQL в MySQL и PostgreSQL. Сравнение возможностей

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;

Page 27: SQL-ник DevDay. Каменский. Расширенный SQL в MySQL и PostgreSQL. Сравнение возможностей

27

Рекурсивные запросы

with [recursive] <имя_алиаса_запроса> [ (<список столбцов>) ]as (<запрос>)<основной запрос>

Page 28: SQL-ник DevDay. Каменский. Расширенный SQL в MySQL и PostgreSQL. Сравнение возможностей

28

Дерево, структура

Page 29: SQL-ник DevDay. Каменский. Расширенный SQL в MySQL и PostgreSQL. Сравнение возможностей

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;

Page 30: SQL-ник DevDay. Каменский. Расширенный SQL в MySQL и PostgreSQL. Сравнение возможностей

30

Вывод рекурсивного запроса

Page 31: SQL-ник DevDay. Каменский. Расширенный SQL в MySQL и PostgreSQL. Сравнение возможностей

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);

Page 32: SQL-ник DevDay. Каменский. Расширенный SQL в MySQL и PostgreSQL. Сравнение возможностей

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

Page 33: SQL-ник DevDay. Каменский. Расширенный SQL в MySQL и PostgreSQL. Сравнение возможностей

33

Page 34: SQL-ник DevDay. Каменский. Расширенный SQL в MySQL и PostgreSQL. Сравнение возможностей

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’);

Page 35: SQL-ник DevDay. Каменский. Расширенный SQL в MySQL и PostgreSQL. Сравнение возможностей

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');

Page 36: SQL-ник DevDay. Каменский. Расширенный SQL в MySQL и PostgreSQL. Сравнение возможностей

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';

Page 37: SQL-ник DevDay. Каменский. Расширенный SQL в MySQL и PostgreSQL. Сравнение возможностей

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;

Page 38: SQL-ник DevDay. Каменский. Расширенный SQL в MySQL и PostgreSQL. Сравнение возможностей

38

Типы таблиц в MySQL

InnoDBMyISAMMemoryMergeArchiveBlackhole

Page 39: SQL-ник DevDay. Каменский. Расширенный SQL в MySQL и PostgreSQL. Сравнение возможностей

39

Типы таблиц в MySQL

tmp_table_size

max_heap_table_size

innodb_table_per_file

Page 40: SQL-ник DevDay. Каменский. Расширенный SQL в MySQL и PostgreSQL. Сравнение возможностей

40

Индексы

Основные типыBtreeHashMySQL – только memory-таблицыPostgreSQL – hash не рекомендуется

Page 41: SQL-ник DevDay. Каменский. Расширенный SQL в MySQL и PostgreSQL. Сравнение возможностей

41

Индексные алгоритмы

MySQL: Невозможность использовать составные индексы при нестрогом равенстве в начале

SELECT * FROM t WHERE a<3 AND b<5;Директива USE/IGNORE/FORCE INDEXPostgreSQL: Невозможность указать индекс

явно.Возможность регуляции черезset enable_***scan=1 и set enable_***scan=0

Page 42: SQL-ник DevDay. Каменский. Расширенный SQL в MySQL и PostgreSQL. Сравнение возможностей

42

Алгоритмы JOIN

MySQL: nested loopPostgreSQL:nested loop joinmerge joinhash join

Page 43: SQL-ник DevDay. Каменский. Расширенный SQL в MySQL и PostgreSQL. Сравнение возможностей

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);

Page 44: SQL-ник DevDay. Каменский. Расширенный SQL в MySQL и PostgreSQL. Сравнение возможностей

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.% ’;

Page 45: SQL-ник DevDay. Каменский. Расширенный SQL в MySQL и PostgreSQL. Сравнение возможностей

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 $$;

Page 46: SQL-ник DevDay. Каменский. Расширенный SQL в MySQL и PostgreSQL. Сравнение возможностей

46

Дополнение

MySQL:Фальшивые Foreign Keys у таблиц MyISAMФальшивые hash-индексы у таблиц не memoryПри @@sql_mode <> ‘ANSI’ возможность делать ошибки

– например SELECT avg(a), b FROM t;PostgreSQL: Отсутствие возможности менять колонки местами Генерация исключений в хранимых процедурах

Page 47: SQL-ник DevDay. Каменский. Расширенный SQL в MySQL и PostgreSQL. Сравнение возможностей

47

Спасибо за внимание!

Page 48: SQL-ник DevDay. Каменский. Расширенный SQL в MySQL и PostgreSQL. Сравнение возможностей

48

Планы исполнения запросов

А.Запрос с ППСинтаксический анализ запросаСоздание плана исполненияОпределение хранилища базы (engine)Цикл foreach {  Обращение к engine }Б.Цикл внутри ХП {  Синтаксический анализ запроса (курсор)  Определение хранилища базы (engine)  Обращение к engine   Переход к следующему шагу цикла (интерпретатор языка SQL)}