Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Planejador de Consultas do PostgreSQL

785 views

Published on

Apresentação sobre o "Query Planner" (planejador de consultas) do PostgreSQL

Published in: Technology, Business
  • Be the first to comment

Planejador de Consultas do PostgreSQL

  1. 1. The PostgreSQL Query Planner
  2. 2. Por que minha consulta (SQL) precisa de um plano?
  3. 3. Simples... ● SQL é declarativo, ou seja, não é um programa ● Não possui controle de fluxo e não tem uma forma de controlar a ordem das operações – A não ser “While” e “For”, mas isso é conversa para outro treinamento ;-) ● SQL pergunta O QUE, e não diz COMO
  4. 4. Planejador/Otimizador é o Cérebro do banco de dados... … pois interpreta consultas SQL e determina o método de execução mais rápido.
  5. 5. Objetivos do Planejador ● Executar consultas mais rapidamente – Diminuir I/O de disco – Priorizar I/O sequencial a I/O randômico – Diminuir uso de CPU ● Não utilizar muita memória no processo ● Entregar resultados corretos
  6. 6. Decisões do planejador ● Método de Pesquisa (Scan Method) ● Método de Junção (Join Method) ● Ordem de Junção (Join Order)
  7. 7. Métodos de Pesquisa (Scan Methods) ● Sequential Scan ● Bitmap Index Scan ● Index Scan
  8. 8. Sequential Scan D A T A D A T A D A T A D A T A D A T A D A T A D A T A D A T A D A T A D A T A D A T A D A T A 8K Heap
  9. 9. Sequential Scan
  10. 10. Bitmap Index Scan 0 1 0 1 AND = 0 1 1 0 0 1 0 0 801 AND 11 Index 1 numcgm = 801 Index 2 receit = 11 Combined Index TABLE
  11. 11. Bitmap Index Scan
  12. 12. Bitmap Index Scan Index 1 k00_numcgm = 801 Index 2 k00_receit = 11 Combined Index (And Operator)
  13. 13. Index Scan key < = > D A T A D A T A D A T A D A T A D A T A D A T A D A T A D A T A D A T A D A T A D A T A D A T A key < = > key < = >
  14. 14. Index Scan
  15. 15. Index Scan
  16. 16. Dúvidas???
  17. 17. Tabela de exemplo
  18. 18. Função para EXPLAIN
  19. 19. Distribuição dos dados
  20. 20. Distribuição dos dados tipo | count | % ------+-------+------ 5 | 14892 | 77.6 34 | 2714 | 14.1 14 | 575 | 3.0 6 | 555 | 2.9 25 | 384 | 2.0 13 | 70 | 0.4 1 | 3 | 0.0 32 | 1 | 0.0 27 | 1 | 0.0 (9 rows)
  21. 21. Planos de execução
  22. 22. tipo | count | % | explain_arrecad ------+-------+------+------------------------------------------------------------------------------- 5 | 14892 | 77.6 | Bitmap Heap Scan on arrecad (cost=3.00..122.14 rows=96 width=52) 5 | 14892 | 77.6 | Recheck Cond: (k00_tipo = 5) 5 | 14892 | 77.6 | -> Bitmap Index Scan on arrecad_tipo_in (cost=0.00..2.97 rows=96 width=0) 5 | 14892 | 77.6 | Index Cond: (k00_tipo = 5) 34 | 2714 | 14.1 | Bitmap Heap Scan on arrecad (cost=3.00..122.14 rows=96 width=52) 34 | 2714 | 14.1 | Recheck Cond: (k00_tipo = 34) 34 | 2714 | 14.1 | -> Bitmap Index Scan on arrecad_tipo_in (cost=0.00..2.97 rows=96 width=0) 34 | 2714 | 14.1 | Index Cond: (k00_tipo = 34) 14 | 575 | 3.0 | Bitmap Heap Scan on arrecad (cost=3.00..122.14 rows=96 width=52) 14 | 575 | 3.0 | Recheck Cond: (k00_tipo = 14) 14 | 575 | 3.0 | -> Bitmap Index Scan on arrecad_tipo_in (cost=0.00..2.97 rows=96 width=0) 14 | 575 | 3.0 | Index Cond: (k00_tipo = 14) 6 | 555 | 2.9 | Bitmap Heap Scan on arrecad (cost=3.00..122.14 rows=96 width=52) 6 | 555 | 2.9 | Recheck Cond: (k00_tipo = 6) 6 | 555 | 2.9 | -> Bitmap Index Scan on arrecad_tipo_in (cost=0.00..2.97 rows=96 width=0) 6 | 555 | 2.9 | Index Cond: (k00_tipo = 6) 25 | 384 | 2.0 | Bitmap Heap Scan on arrecad (cost=3.00..122.14 rows=96 width=52) 25 | 384 | 2.0 | Recheck Cond: (k00_tipo = 25) 25 | 384 | 2.0 | -> Bitmap Index Scan on arrecad_tipo_in (cost=0.00..2.97 rows=96 width=0) 25 | 384 | 2.0 | Index Cond: (k00_tipo = 25) 13 | 70 | 0.4 | Bitmap Heap Scan on arrecad (cost=3.00..122.14 rows=96 width=52) 13 | 70 | 0.4 | Recheck Cond: (k00_tipo = 13) 13 | 70 | 0.4 | -> Bitmap Index Scan on arrecad_tipo_in (cost=0.00..2.97 rows=96 width=0) 13 | 70 | 0.4 | Index Cond: (k00_tipo = 13) 1 | 3 | 0.0 | Bitmap Heap Scan on arrecad (cost=3.00..122.14 rows=96 width=52) 1 | 3 | 0.0 | Recheck Cond: (k00_tipo = 1) 1 | 3 | 0.0 | -> Bitmap Index Scan on arrecad_tipo_in (cost=0.00..2.97 rows=96 width=0) 1 | 3 | 0.0 | Index Cond: (k00_tipo = 1) 27 | 1 | 0.0 | Bitmap Heap Scan on arrecad (cost=3.00..122.14 rows=96 width=52) 27 | 1 | 0.0 | Recheck Cond: (k00_tipo = 27) 27 | 1 | 0.0 | -> Bitmap Index Scan on arrecad_tipo_in (cost=0.00..2.97 rows=96 width=0) 27 | 1 | 0.0 | Index Cond: (k00_tipo = 27) 32 | 1 | 0.0 | Bitmap Heap Scan on arrecad (cost=3.00..122.14 rows=96 width=52) 32 | 1 | 0.0 | Recheck Cond: (k00_tipo = 32) 32 | 1 | 0.0 | -> Bitmap Index Scan on arrecad_tipo_in (cost=0.00..2.97 rows=96 width=0) 32 | 1 | 0.0 | Index Cond: (k00_tipo = 32) (36 rows)
  23. 23. Tá bom, só uma linha do EXPLAIN
  24. 24. Melhorou agora? tipo | count | % | explain_arrecad ------+-------+------+------------------------------------------------------------------- 5 | 14892 | 77.6 | Bitmap Heap Scan on arrecad (cost=3.00..122.14 rows=96 width=52) 34 | 2714 | 14.1 | Bitmap Heap Scan on arrecad (cost=3.00..122.14 rows=96 width=52) 14 | 575 | 3.0 | Bitmap Heap Scan on arrecad (cost=3.00..122.14 rows=96 width=52) 6 | 555 | 2.9 | Bitmap Heap Scan on arrecad (cost=3.00..122.14 rows=96 width=52) 25 | 384 | 2.0 | Bitmap Heap Scan on arrecad (cost=3.00..122.14 rows=96 width=52) 13 | 70 | 0.4 | Bitmap Heap Scan on arrecad (cost=3.00..122.14 rows=96 width=52) 1 | 3 | 0.0 | Bitmap Heap Scan on arrecad (cost=3.00..122.14 rows=96 width=52) 27 | 1 | 0.0 | Bitmap Heap Scan on arrecad (cost=3.00..122.14 rows=96 width=52) 32 | 1 | 0.0 | Bitmap Heap Scan on arrecad (cost=3.00..122.14 rows=96 width=52) (9 rows)
  25. 25. Nada mudou né... ● Alguém arrisca dizer porque os planos estão iguais??? ● Mesmo buscando qtds diferentes de dados da tabela???
  26. 26. Estatísticas desatualizadas
  27. 27. Estatísticas desatualizadas
  28. 28. ANALYZE é seu amigo... Esses valores não são familiares???
  29. 29. Verificar planos de novo...
  30. 30. Interessante não? tipo | count | % | explain_arrecad ------+-------+------+---------------------------------------------------------------------------------- 5 | 14892 | 77.6 | Seq Scan on arrecad (cost=0.00..499.94 rows=14892 width=52) 34 | 2714 | 14.1 | Bitmap Heap Scan on arrecad (cost=39.28..333.21 rows=2714 width=52) 14 | 575 | 3.0 | Bitmap Heap Scan on arrecad (cost=8.71..275.89 rows=575 width=52) 6 | 555 | 2.9 | Bitmap Heap Scan on arrecad (cost=8.55..275.49 rows=555 width=52) 25 | 384 | 2.0 | Bitmap Heap Scan on arrecad (cost=7.23..250.28 rows=384 width=52) 13 | 70 | 0.4 | Index Scan using arrecad_tipo_in on arrecad (cost=0.00..29.27 rows=19 width=52) 1 | 3 | 0.0 | Index Scan using arrecad_tipo_in on arrecad (cost=0.00..29.27 rows=19 width=52) 32 | 1 | 0.0 | Index Scan using arrecad_tipo_in on arrecad (cost=0.00..29.27 rows=19 width=52) 27 | 1 | 0.0 | Index Scan using arrecad_tipo_in on arrecad (cost=0.00..29.27 rows=19 width=52) (9 rows)
  31. 31. Vamos forçar um “IndexScan”?
  32. 32. Ficou mais rápido?? tipo | count | % | explain_arrecad ------+-------+------+------------------------------------------------------------------------------ 5 | 14892 | 77.6 | Index Scan using arrecad_tipo_in on arrecad (cost=0.00..779.24 rows=14892 wi 34 | 2714 | 14.1 | Index Scan using arrecad_tipo_in on arrecad (cost=0.00..434.27 rows=2714 wid 14 | 575 | 3.0 | Index Scan using arrecad_tipo_in on arrecad (cost=0.00..373.73 rows=575 widt 6 | 555 | 2.9 | Index Scan using arrecad_tipo_in on arrecad (cost=0.00..373.38 rows=555 widt 25 | 384 | 2.0 | Index Scan using arrecad_tipo_in on arrecad (cost=0.00..316.27 rows=384 widt 13 | 70 | 0.4 | Index Scan using arrecad_tipo_in on arrecad (cost=0.00..29.27 rows=19 width= 1 | 3 | 0.0 | Index Scan using arrecad_tipo_in on arrecad (cost=0.00..29.27 rows=19 width= 27 | 1 | 0.0 | Index Scan using arrecad_tipo_in on arrecad (cost=0.00..29.27 rows=19 width= 32 | 1 | 0.0 | Index Scan using arrecad_tipo_in on arrecad (cost=0.00..29.27 rows=19 width= (9 rows) tipo | count | % | explain_arrecad ------+-------+------+------------------------------------------------------------------------------ 5 | 14892 | 77.6 | Seq Scan on arrecad (cost=0.00..499.94 rows=14892 width=52) 34 | 2714 | 14.1 | Bitmap Heap Scan on arrecad (cost=39.28..333.21 rows=2714 width=52) 14 | 575 | 3.0 | Bitmap Heap Scan on arrecad (cost=8.71..275.89 rows=575 width=52) 6 | 555 | 2.9 | Bitmap Heap Scan on arrecad (cost=8.55..275.49 rows=555 width=52) 25 | 384 | 2.0 | Bitmap Heap Scan on arrecad (cost=7.23..250.28 rows=384 width=52) 13 | 70 | 0.4 | Index Scan using arrecad_tipo_in on arrecad (cost=0.00..29.27 rows=19 width= 1 | 3 | 0.0 | Index Scan using arrecad_tipo_in on arrecad (cost=0.00..29.27 rows=19 width= 32 | 1 | 0.0 | Index Scan using arrecad_tipo_in on arrecad (cost=0.00..29.27 rows=19 width= 27 | 1 | 0.0 | Index Scan using arrecad_tipo_in on arrecad (cost=0.00..29.27 rows=19 width= (9 rows)
  33. 33. DICA! “Não tente ser mais esperto que o planejador.” Mas ele não é “infalível”, se você já tentou de tudo e mesmo assim tem problemas, colabore seu plano conosco e nos ajude a melhorá-lo: pgsql-performance@postgresql.org pgsql-hackers@postgresql.org
  34. 34. Métodos de Junção (Join Methods) ● Nested Loop – With inner Sequencial Scan – With inner Index Scan ● Hash Join ● Merge Join
  35. 35. Junção de duas tabelas com alta restrição (=)
  36. 36. Junção de duas tabelas com alta restrição (=)
  37. 37. Nested Loop (with Inner Sequencial Scan) 4 1 3 2 1 3 4 5 2 7 6 Outer Inner
  38. 38. Nested Loop (with Inner Sequencial Scan) 4 1 3 2 1 3 4 5 2 7 6 Outer Inner
  39. 39. Nested Loop (with Inner Sequencial Scan) 4 1 3 2 1 3 4 5 2 7 6 Outer Inner
  40. 40. Nested Loop (with Inner Sequencial Scan) 4 1 3 2 1 3 4 5 2 7 6 Outer Inner
  41. 41. Pseudocode for Nested Loop (with Inner Sequencial Scan)
  42. 42. Junção de duas tabelas com baixa restrição (>, <, <>)
  43. 43. Junção de duas tabelas com baixa restrição (>, <, <>)
  44. 44. Hash Join 4 1 3 2 1 34 5 2 7 6 Outer Inner Deve caber na RAM Hashed
  45. 45. Pseudocode for Hash Join
  46. 46. Junção de duas tabelas sem restrição
  47. 47. Junção de duas tabelas sem restrição
  48. 48. Merge Join Outer Inner Ideal para grandes tabelas Um índice pode ser usado para eliminar o “Sort” 2 3 4 1 2 2 3 1 4 5 4 Sorted Sorted
  49. 49. Pseudocode for Merge Join
  50. 50. Algumas considerações ● Ordem das junções é insignificante ● Outer Joins (left, right) podem afetar o otimizador ● Nested Loop pode usar índice na pesquisa ● Restrições (where) afetam o uso de junções ● LIMIT pode afetar o uso de junções
  51. 51. Dúvidas???

×