empathy optymalizacja postgre_sql
TRANSCRIPT
Jak optymalizować bazy danych
w aplikacjach internetowych.
Na przykładzie PostgreSQL.
Wojciech Bublik
O EmpathyInternet Software House
www.empathy.pl
2000rok założenia
30 osób
zatrudnienie
O czym będę mówił?
www.empathy.pl
1. Tuning konfiguracji serwera
2. O czym powinni pamiętać programiści
3. Optymalizacja zapytań na podstawie
analizy bazy danych
4. Inne możliwości optymalizacji…
Tuning konfiguracji serwera
www.empathy.pl
postgresql.conf
max_connections
shared_buffers
temp_buffers
max_prepared_transactions
work_mem
maintenance_work_mem
checkpoint_segments
effective_cache_size
Tuning konfiguracji serwera
www.empathy.pl
Konfiguracja systemu: /etc/sysctl.confhttp://www.postgresql.org/docs/8.3/interactive/kernel-resources.html
kern.ipc.shmall
kern.ipc.shmmax
kern.ipc.semmap
Tuning konfiguracji serwera
www.empathy.pl
Konfiguracja sprzętowa
1. Szybkie dyski twarde – duży cache, RAID
2. Wiele procesorów – każde połączenie to oddzielny
proces
3. Duża ilość pamięci RAM
Optymalizacja zapytańO czym programiści powinni pamiętać
www.empathy.pl
1. Indeksy
CREATE INDEX idx_test1
ON mtcs_attributes
(fk_attribute_class_id);
CREATE INDEX idx_test2
ON opr_cttrx
(ctt_amnt, ctt_sysdate)
WITH (fillfactor = 70);
CREATE INDEX idx_test3
ON opr_pptrx
USING btree
(ppt_date)
WHERE ppt_acc = 5504100;
Optymalizacja zapytańO czym programiści powinni pamiętać
www.empathy.pl
2. Pola w wynikach zapytania
Optymalizacja zapytańO czym programiści powinni pamiętać
www.empathy.pl
3. Minimalizowanie ilości zapytań SQL
1. SELECT true FROM eicrm_company WHERE cmp_id = 1234;
UPDATE eicrm_company
SET cmp_name = ‘xyz’, cmp_short_name = ‘xyz’
WHERE cmp_id = 1234;
INSERT INTO eicrm_company (cmp_name, cmp_short_name)
VALUES (‘xyz’,’xyz’);
2. UPDATE eicrm_company
SET cmp_name = ‘xyz’, cmp_short_name = ‘xyz’
WHERE cmp_id = 1234
RETURNING cmp_id;
INSERT INTO eicrm_company (cmp_name, cmp_short_name)
VALUES (‘xyz’,’xyz’) RETURNING cmp_id;
Optymalizacja zapytańO czym programiści powinni pamiętać
www.empathy.pl
3. Przetwarzanie dużych ilości danych
• Transakcje,
• Prepared Statements,
• Multi-row insert,
• Copy
Optymalizacja zapytańO czym programiści powinni pamiętać
www.empathy.pl
4. Postać normalna? Nie za wszelką cenę.
CREATE TABLE eicrm_company
(
cmp_id serial NOT NULL,
cmp_short_name character varying(64) NOT NULL,
cmp_name character varying(256) NOT NULL,
cmp_nip character varying(10)
);
CREATE TABLE eicrm_address
(
adr_id serial NOT NULL,
adr_cmp_id integer,
adr_street character varying(256),
adr_street_no integer,
adr_street_place_no character varying(8),
adr_city character varying(256),
adr_postal_code character varying(6)
);
CREATE TABLE eicrm_phone
(
phn_id serial NOT NULL,
phn_cmp_id integer,
phn_no character varying(16),
phn_type smallint,
);
CREATE TABLE eicrm_www
(
www_id serial NOT NULL,
www_cmp_id integer,
www_address character varying(64)
);
Optymalizacja zapytańO czym programiści powinni pamiętać
www.empathy.pl
5. Widoki
• Przejrzystość zapytań SQL
• Pomocnicza warstwa logiki w bazie danych
• Możliwość optymalizacji zapytań bez zmian w kodzie
aplikacji
• Możliwość konwersji na zmaterializowane widoki
Optymalizacja zapytańO czym programiści powinni pamiętać
www.empathy.pl
6. Warto próbować różnych sposobów
COST: 8173 CZAS WYKONANIA: 108 ms
SELECT eis_product_group.pgr_id, max(eis_product_group.pgr_name)
FROM eis_product_group
LEFT OUTER JOIN tmp_prd_list_view ON (eis_product_group.pgr_id = tmp_prd_list_view.pgr_id)
GROUP BY eis_product_group.pgr_id HAVING count(tmp_prd_list_view.pgr_id) > 0
COST: 9940 CZAS WYKONANIA: 108 ms
SELECT DISTINCT eis_product_group.pgr_id, eis_product_group.pgr_name
FROM eis_product_group
INNER JOIN tmp_prd_list_view ON (eis_product_group.pgr_id = tmp_prd_list_view.pgr_id)
COST: 9340 CZAS WYKONANIA: 108 ms
SELECT eis_product_group.pgr_id, eis_product_group.pgr_name
FROM eis_product_group
WHERE pgr_id IN (SELECT DISTINCT pgr_id FROM tmp_prd_list_view)
Optymalizacja zapytańO czym programiści powinni pamiętać
www.empathy.pl
6. Warto próbować różnych sposobów
COST: 14 CZAS WYKONANIA: 13 ms
SELECT
eis_product_group.pgr_id, eis_product_group.pgr_name
FROM eis_product_group
WHERE pgr_id IN (SELECT pgr_id FROM tmp_prd_list_view)
COST: 89 CZAS WYKONANIA: 21 ms
SELECT eis_product_group.pgr_id, eis_product_group.pgr_name
FROM eis_product_group
WHERE
EXISTS
(SELECT 1 FROM tmp_prd_list_view WHERE tmp_prd_list_view.pgr_id = eis_product_group.pgr_id)
Optymalizacja zapytańAnaliza bazy danych
www.empathy.pl
Analiza bazy danych
1. Analiza statystyk serwera
track_counts (stats_start_collector, stats_row_level),
pg_stat_user_tables, pg_stat_user_indexes
2. Analiza logów
log_min_duration_statement, pgFouine
Optymalizacja zapytańAnaliza bazy danych
www.empathy.pl
Analiza statystyk serwera
postgresql.conf:
track_counts (stats_start_collector, stats_row_level)
SELECT * FROM pg_stat_user_tables;
SELECT * FROM pg_stat_user_indexes;
Optymalizacja zapytańAnaliza bazy danych - analiza statystyk serwera
www.empathy.pl
Optymalizacja zapytańAnaliza bazy danych - analiza statystyk serwera
www.empathy.pl
Optymalizacja zapytańAnaliza bazy danych
www.empathy.pl
Analiza logów serwera
postgresql.conf:
log_statement, log_min_duration_statement
Optymalizacja zapytańAnaliza bazy danych - analiza logów serwera
www.empathy.pl
pgFouine (http://pgfouine.projects.postgresql.org)
php pgfouine.php -file postgresql.log > sample_default.html
Optymalizacja zapytańAnaliza bazy danych - analiza logów serwera
www.empathy.pl
Optymalizacja zapytańAnaliza bazy danych - analiza logów serwera
www.empathy.pl
Optymalizacja zapytańAnaliza bazy danych - analiza logów serwera
www.empathy.pl
Optymalizacja zapytańExplain, przykład optymalizacji SQL
www.empathy.pl
SELECT
eicrm_user.usr_id, eicrm_user.usr_status, eicrm_user.usr_fname, eicrm_user.usr_lname,
eicrm_user.usr_street_prefix, eicrm_user.usr_street, eicrm_user.usr_street_no,
eicrm_user.usr_street_place_no, eicrm_user.usr_city, eicrm_user.usr_postal_code,
eicrm_user.usr_post, eicrm_user.usr_email, eicrm_user.usr_phone_no,
eicrm_user.usr_mobilephone_no, eicrm_user_type.utp_name,eicrm_company.cmp_city,
eicrm_company.cmp_street, eicrm_company.cmp_name,
(
SELECT pnc_name FROM eicrm_province WHERE eicrm_user.usr_pnc_id = eicrm_province.pnc_id
) as pnc_name
FROM eicrm_user
JOIN eicrm_user_user_type ON eicrm_user_user_type.uut_usr_id = eicrm_user.usr_id
JOIN eicrm_user_type ON eicrm_user_user_type.uut_utp_id = eicrm_user_type.utp_id
LEFT OUTER JOIN eicrm_user_company ON eicrm_user_company.ucm_usr_id = eicrm_user.usr_id
LEFT OUTER JOIN eicrm_company ON eicrm_company.cmp_id = eicrm_user_company.ucm_cmp_id
WHERE
eicrm_user_user_type.uut_utp_id = 13 AND
eicrm_user.usr_lname = 'Kowalski' AND
eicrm_user.usr_city = 'Kraków'
LIMIT 100
Optymalizacja zapytańExplain, przykład optymalizacji SQL
www.empathy.pl
Bez warunków, bez limit 100
Optymalizacja zapytańExplain, przykład optymalizacji SQL
www.empathy.pl
Bez warunków, z limit 100
Optymalizacja zapytańExplain, przykład optymalizacji SQL
www.empathy.pl
Z warunkamieicrm_user.usr_lname = 'Kowalski'
eicrm_user.usr_city = 'Kraków'
bez indeksu na warunkach
Optymalizacja zapytańExplain, przykład optymalizacji SQL
www.empathy.pl
Z warunkamieicrm_user.usr_lname = 'Kowalski'
eicrm_user.usr_city = 'Kraków'
z indeksem usr_lname, usr_city
Optymalizacja zapytańExplain, przykład optymalizacji SQL
www.empathy.pl
Z warunkamieicrm_user.usr_lname = 'Kowalski'
eicrm_user.usr_city = 'Kraków'
z indeksami usr_lname oraz usr_city
Optymalizacja zapytańInne możliwości optymalizacji
www.empathy.pl
Zmaterializowane widokihttp://tech.jonathangardner.net/wiki/PostgreSQL/Materialized_Views
• Tabela na podstawie wyników zapytania SQL zawierająca snapshot danych
• Odświeżana cyklicznie lub z poziomu triggerów w tabelach
• Możliwości indeksowania zmaterializowanego widoku
• Proste i skuteczne rozwiązanie dające bardzo duży wzrost wydajności
• Zagrożenia! Kopia nie odzwierciedla aktualnego stanu bazy danych.
Optymalizacja zapytańInne możliwości optymalizacji
www.empathy.pl
Partycjonowanie tabelconstraint_exclusion = on
• Podział dużej tabeli na wiele mniejszych
• Bardzo duży wzrost wydajności zapytań – zapytania skierowane na tabele
z odpowiednim fragmentem danych
• Ułatwione zarządzanie danymi – przechowywanie danych na wielu tablespace
• Niezależne blokowanie tabel
• Brak unikalności klucza głównego
Optymalizacja zapytańInne możliwości optymalizacji
www.empathy.pl
Partycjonowanie tabelCREATE TABLE opr_okktr
(
okk_id serial NOT NULL,
okk_trnref character varying(25),
okk_date date NOT NULL,
okk_datelocal date,
okk_crdno character varying(19),
okk_acc bigint NOT NULL,
okk_amnt numeric(14,2),
okk_curr_id smallint,
okk_amntset numeric(14,2),
okk_currset_id smallint,
okk_dateset date,
okk_amntbill numeric(14,2),
okk_currbill_id smallint,
okk_ctt_id integer,
okk_ref text,
CONSTRAINT okk_id PRIMARY KEY (okk_id),
);
CREATE TABLE opr_okktr_201001
(
CONSTRAINT opr_okktr_201001_date_check
CHECK (
okk_date >= '2010-01-01'::date
AND
okk_date < '2010-02-01'::date
)
) INHERITS (opr_okktr);
CREATE TABLE opr_okktr_201002
(
CONSTRAINT opr_okktr_201002_date_check
CHECK (
okk_date >= '2010-02-01'::date
AND
okk_date < '2010-03-01'::date
)
) INHERITS (opr_okktr);
Optymalizacja zapytańInne możliwości optymalizacji
www.empathy.pl
Partycjonowanie tabel
CREATE OR REPLACE RULE opr_okktr_ins201001 AS
ON INSERT TO opr_okktr
WHERE
new.okk_date >= '2010-01-01'::date AND new.okk_date < '2010-02-01'::date
DO INSTEAD
INSERT INTO opr_okktr_201001
(okk_id, okk_trnref, okk_date, okk_datelocal, okk_crdno, okk_acc, okk_amnt,
okk_curr_id, okk_amntset, okk_currset_id, okk_dateset, okk_amntbill,
okk_currbill_id, okk_ctt_id, okk_ref)
VALUES
(new.okk_id, new.okk_trnref, new.okk_date, new.okk_datelocal, new.okk_crdno,
new.okk_acc, new.okk_amnt, new.okk_curr_id, new.okk_amntset, new.okk_currset_id,
new.okk_dateset, new.okk_amntbill, new.okk_currbill_id, new.okk_ctt_id,
new.okk_ref);
Optymalizacja zapytańInne możliwości optymalizacji
www.empathy.pl
Partycjonowanie tabel
Optymalizacja zapytańInne możliwości optymalizacji
www.empathy.pl
Partycjonowanie tabel
www.empathy.pl
1. Wejdź na
www.empathy.pl/facebook
2. „Polub” naszą stronę
3. Skomentuj wpis ze
zdjęciem z Tech.Spodka
4. Hasło: „Konkurs”
5. Wygraj nagrodę:)
KonkursFacebook