[{"data":1,"prerenderedAt":203},["ShallowReactive",2],{"blog-how-to-optimize-databases-postgresql-and-redis":3},{"title":4,"description":7,"image":10,"category":11,"featured":12,"isPublished":12,"publishDate":13,"author":14,"links":15,"projects":18,"mainLanguage":19,"viewCount":20,"value":21,"content":22,"tableOfContents":25},{"en":5,"pl":6},"How to optimize databases: PostgreSQL and Redis","Jak zoptymalizować bazy danych: PostgreSQL i Redis",{"en":8,"pl":9},"Practical guide to PostgreSQL optimization with indexes, partitioning, and EXPLAIN ANALYZE, plus Redis caching patterns for high-traffic production apps.","Praktyczny przewodnik po optymalizacji PostgreSQL — indeksy, partycjonowanie, EXPLAIN ANALYZE — oraz wzorce cachowania w Redis dla produkcyjnych aplikacji.","https://files.jtuta.cloud/public/portfolio/blogs/jinojiquY0qzooKhE6fLfJ6fZGd0SS.png","data bases",true,"2025-11-30T22:53:21.565Z",null,[16,17],"https://redis.io","https://www.postgresql.org.pl",[],"pl",1,"how-to-optimize-databases-postgresql-and-redis",{"en":23,"pl":24},"\u003Ch2 id=\"database-optimization-in-production-postgresql-and-redis\" tabindex=\"-1\">Database Optimization in Production: PostgreSQL and Redis\u003C/h2>\n\u003Cp>Imagine your application starts to slow down. Users wait seconds instead of milliseconds for data to load. The admin dashboard sometimes doesn't load at all. Sound familiar? In most cases, the problem lies in the database — poorly designed queries, lack of indexes, growing tables without partitioning. And once you add the right indexes, another challenge arises: how to speed up the system even further?\u003C/p>\n\u003Cp>You'll find the answers to these questions in two tools: PostgreSQL optimization and intelligent caching with Redis. In this article, I'll show you specific techniques I use in production projects handling millions of requests daily. There will be no textbook theory — only practical examples with code and explanations of when and why a particular solution works.\u003C/p>\n\u003Cp>We'll start with the fundamentals of PostgreSQL optimization: indexes, partitioning, and other tricks that will turn slow queries into lightning-fast ones. Then we'll move on to Redis — I'll show you how this technology works, why it's so fast, and how to use it to create an efficient cache layer for hot data.\u003C/p>\n\u003Ch2 id=\"indexes-in-postgresql-when-and-how-to-use-them\" tabindex=\"-1\">Indexes in PostgreSQL — when and how to use them\u003C/h2>\n\u003Cp>Indexes are the most important database optimization tool. Instead of scanning the entire table row by row \u003Cem>(sequential scan)\u003C/em>, PostgreSQL uses an index to find exactly the records you need. It's like the difference between reading a book cover to cover and using the index at the back of the book.\u003C/p>\n\u003Ch3 id=\"b-tree-the-basic-index-for-every-occasion\" tabindex=\"-1\">B-Tree — the basic index for every occasion\u003C/h3>\n\u003Cp>The B-Tree index is the default index type in PostgreSQL and the most commonly used. It works perfectly for queries with comparison operators \u003Ccode>=\u003C/code>, \u003Ccode>&lt;\u003C/code>, \u003Ccode>&gt;\u003C/code>, \u003Ccode>&lt;=\u003C/code>, \u003Ccode>&gt;=\u003C/code>, \u003Ccode>BETWEEN\u003C/code>, and \u003Ccode>ORDER BY\u003C/code>.\u003C/p>\n\u003Cpre class=\"shiki shiki-themes github-light github-dark\" style=\"background-color:light-dark(#fff, #24292e);--shiki-light-bg:#fff;--shiki-dark-bg:#24292e;color:light-dark(#24292e, #e1e4e8);--shiki-light:#24292e;--shiki-dark:#e1e4e8\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Przykład: tabela użytkowników\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">CREATE\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> TABLE\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> users\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> (\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    id \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">SERIAL\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> PRIMARY KEY\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,  \u003C/span>\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- PostgreSQL automatycznie tworzy indeks B-Tree na PRIMARY KEY\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    email \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">VARCHAR\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">255\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">NOT NULL\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    created_at \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">TIMESTAMP\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> DEFAULT\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> NOW\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(),\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    last_login \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">TIMESTAMP\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Dodajemy indeks na email - często wyszukujemy użytkowników po emailu\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">CREATE\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> INDEX\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> idx_users_email\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> ON\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> users(email);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Indeks na created_at - często filtrujemy użytkowników po dacie rejestracji\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">CREATE\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> INDEX\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> idx_users_created_at\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> ON\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> users(created_at);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\u003C/code>\u003C/pre>\n\u003Cp>When won't this index help? When you select most of the rows from the table. If a query returns 20-30% of all records, PostgreSQL will likely perform a \u003Ccode>sequential scan\u003C/code> because it will be faster than jumping through the index.\u003C/p>\n\u003Ch3 id=\"multi-column-indexes-order-matters\" tabindex=\"-1\">Multi-column indexes — order matters\u003C/h3>\n\u003Cp>You can create an index on several columns at once. Very important: the order of columns is crucial.\u003C/p>\n\u003Cpre class=\"shiki shiki-themes github-light github-dark\" style=\"background-color:light-dark(#fff, #24292e);--shiki-light-bg:#fff;--shiki-dark-bg:#24292e;color:light-dark(#24292e, #e1e4e8);--shiki-light:#24292e;--shiki-dark:#e1e4e8\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Przykład: tabela zamówień\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">CREATE\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> TABLE\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> orders\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> (\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    id \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">SERIAL\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> PRIMARY KEY\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    user_id \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">INTEGER\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> NOT NULL\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">    status\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> VARCHAR\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">50\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">NOT NULL\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,  \u003C/span>\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- 'pending', 'paid', 'shipped', 'delivered'\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    created_at \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">TIMESTAMP\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> DEFAULT\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> NOW\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(),\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    total_amount \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">DECIMAL\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">10\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">2\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- DOBRZE: Najczęściej filtrujemy po user_id, a potem po status\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">CREATE\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> INDEX\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> idx_orders_user_status\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> ON\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> orders(user_id, \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">status\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- To zapytanie UŻYJE indeksu:\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">SELECT\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> *\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> FROM\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> orders \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">WHERE\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> user_id \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">=\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> 123\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> AND\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> status\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> =\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> 'pending'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- To zapytanie też UŻYJE indeksu (częściowo):\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">SELECT\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> *\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> FROM\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> orders \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">WHERE\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> user_id \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">=\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> 123\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- To zapytanie NIE UŻYJE indeksu (brak pierwszej kolumny z indeksu):\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">SELECT\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> *\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> FROM\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> orders \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">WHERE\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> status\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> =\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> 'pending'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\u003C/code>\u003C/pre>\n\u003Cp>The rule is simple: a multicolumn index works from left to right. If you don't use the first column of the index in your query, the index won't work. For the example above, if you often search only by \u003Ccode>status\u003C/code>, you need a separate index:\u003C/p>\n\u003Cpre class=\"shiki shiki-themes github-light github-dark\" style=\"background-color:light-dark(#fff, #24292e);--shiki-light-bg:#fff;--shiki-dark-bg:#24292e;color:light-dark(#24292e, #e1e4e8);--shiki-light:#24292e;--shiki-dark:#e1e4e8\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Dodatkowy indeks tylko na status\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">CREATE\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> INDEX\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> idx_orders_status\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> ON\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> orders(\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">status\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch3 id=\"partial-indexes-smaller-and-faster\" tabindex=\"-1\">Partial indexes — smaller and faster\u003C/h3>\n\u003Cp>If you are only interested in a subset of data, create a partial index. It will be smaller, faster to update, and equally efficient for specific queries.\u003C/p>\n\u003Cpre class=\"shiki shiki-themes github-light github-dark\" style=\"background-color:light-dark(#fff, #24292e);--shiki-light-bg:#fff;--shiki-dark-bg:#24292e;color:light-dark(#24292e, #e1e4e8);--shiki-light:#24292e;--shiki-dark:#e1e4e8\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Indeks tylko na aktywne zamówienia (status != 'delivered')\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Te zamówienia stanowią zazwyczaj małą część tabeli\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">CREATE\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> INDEX\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> idx_orders_active\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> ON\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> orders(user_id, \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">status\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">WHERE\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> status\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> !=\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> 'delivered'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- To zapytanie użyje indeksu częściowego:\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">SELECT\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> *\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> FROM\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> orders \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">WHERE\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> user_id \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">=\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> 123\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> AND\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> status\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> =\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> 'pending'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Możemy stworzyć indeks tylko na zamówienia z ostatnich 30 dni\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">CREATE\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> INDEX\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> idx_orders_recent\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> ON\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> orders(created_at) \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">WHERE\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> created_at \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">>\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> NOW\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">() \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">-\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> INTERVAL \u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'30 days'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\u003C/code>\u003C/pre>\n\u003Cp>Why does this make sense? In a typical e-commerce application, 95% of orders are already completed \u003Ccode>(delivered)\u003C/code>. You need quick access to active orders. A partial index will be 20 times smaller and significantly faster to update.\u003C/p>\n\u003Ch3 id=\"gin-index-for-jsonb-and-full-text-search\" tabindex=\"-1\">GIN — index for JSONB and full-text search\u003C/h3>\n\u003Cp>When you store data in JSONB format or need full-text search, a B-Tree index is not enough. Use GIN \u003Cem>(Generalized Inverted Index)\u003C/em>.\u003C/p>\n\u003Cpre class=\"shiki shiki-themes github-light github-dark\" style=\"background-color:light-dark(#fff, #24292e);--shiki-light-bg:#fff;--shiki-dark-bg:#24292e;color:light-dark(#24292e, #e1e4e8);--shiki-light:#24292e;--shiki-dark:#e1e4e8\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Tabela produktów z dodatkowymi atrybutami w JSONB\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">CREATE\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> TABLE\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> products\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> (\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    id \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">SERIAL\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> PRIMARY KEY\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">    name\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> VARCHAR\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">255\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">NOT NULL\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    attributes JSONB  \u003C/span>\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- przykład: {\"color\": \"red\", \"size\": \"large\", \"tags\": [\"sale\", \"new\"]}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Indeks GIN na całej kolumnie JSONB\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">CREATE\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> INDEX\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> idx_products_attributes\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> ON\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> products \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">USING\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> GIN(attributes);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Teraz możesz szybko wyszukiwać po atrybutach:\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">SELECT\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> *\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> FROM\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> products \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">WHERE\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> attributes @\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">>\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> '{\"color\": \"red\"}'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Wyszukiwanie po zagnieżdżonych wartościach:\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">SELECT\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> *\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> FROM\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> products \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">WHERE\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> attributes @\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">>\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> '{\"tags\": [\"sale\"]}'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Operatory dla JSONB:\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- @> zawiera (contains)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- ? istnieje klucz\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- ?| istnieje którykolwiek z kluczy\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- ?&#x26; istnieją wszystkie klucze\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\u003C/code>\u003C/pre>\n\u003Cp>Example with full-text search:\u003C/p>\n\u003Cpre class=\"shiki shiki-themes github-light github-dark\" style=\"background-color:light-dark(#fff, #24292e);--shiki-light-bg:#fff;--shiki-dark-bg:#24292e;color:light-dark(#24292e, #e1e4e8);--shiki-light:#24292e;--shiki-dark:#e1e4e8\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Dodajemy kolumnę z wektorem wyszukiwania\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">ALTER\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> TABLE\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> products \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">ADD\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> COLUMN search_vector tsvector;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Tworzymy GIN indeks na wektorze\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">CREATE\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> INDEX\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> idx_products_search\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> ON\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> products \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">USING\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> GIN(search_vector);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Aktualizujemy wektor przy każdej zmianie (możesz to zautomatyzować triggerem)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">UPDATE\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> products \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">SET\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> search_vector \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">=\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> to_tsvector(\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'english'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">name\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> ||\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> ' '\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> ||\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> COALESCE\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">description\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">''\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">));\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Szybkie wyszukiwanie pełnotekstowe:\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">SELECT\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> *\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> FROM\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> products \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">WHERE\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> search_vector @@ to_tsquery(\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'english'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'laptop &#x26; gaming'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch3 id=\"brin-efficient-index-for-huge-tables\" tabindex=\"-1\">BRIN — efficient index for huge tables\u003C/h3>\n\u003Cp>BRIN \u003Cem>(Block Range Index)\u003C/em> is an index that stores only the minimum and maximum values for data blocks. It is ideal for very large tables with naturally ordered data, such as logs or time-series data.\u003C/p>\n\u003Cpre class=\"shiki shiki-themes github-light github-dark\" style=\"background-color:light-dark(#fff, #24292e);--shiki-light-bg:#fff;--shiki-dark-bg:#24292e;color:light-dark(#24292e, #e1e4e8);--shiki-light:#24292e;--shiki-dark:#e1e4e8\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Tabela logów systemowych\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">CREATE\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> TABLE\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> system_logs\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> (\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    id \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">BIGSERIAL\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> PRIMARY KEY\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    log_time \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">TIMESTAMP\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> NOT NULL\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">    level\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> VARCHAR\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">20\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">),\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">    message\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> TEXT\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Zamiast gigantycznego B-Tree, używamy BRIN\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">CREATE\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> INDEX\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> idx_logs_time\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> ON\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> system_logs \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">USING\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> BRIN(log_time);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Zapytania po zakresach czasu będą bardzo szybkie:\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">SELECT\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> *\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> FROM\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> system_logs \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">WHERE\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> log_time \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">BETWEEN\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> '2025-11-01'\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> AND\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> '2025-11-30'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\u003C/code>\u003C/pre>\n\u003Cp>Advantages of BRIN:\u003C/p>\n\u003Cul>\n\u003Cli>Index takes 1000x less space than B-Tree\u003C/li>\n\u003Cli>Very fast creation and update\u003C/li>\n\u003Cli>Excellent for chronologically inserted data\u003C/li>\n\u003C/ul>\n\u003Cp>Disadvantages:\u003C/p>\n\u003Cul>\n\u003Cli>Only works for naturally ordered data\u003C/li>\n\u003Cli>Less precise than B-Tree\u003C/li>\n\u003C/ul>\n\u003Ch3 id=\"when-not-to-create-indexes\" tabindex=\"-1\">When NOT to create indexes?\u003C/h3>\n\u003Cp>Indexes have a cost — they take up space and slow down \u003Ccode>INSERT\u003C/code>, \u003Ccode>UPDATE\u003C/code>, and \u003Ccode>DELETE\u003C/code> operations. Do not create an index when:\u003C/p>\n\u003Cul>\n\u003Cli>The table is very small \u003Cem>(below 1000 rows)\u003C/em> — sequential scan will be faster\u003C/li>\n\u003Cli>The column has very low cardinality \u003Cem>(e.g., a boolean column with 50% TRUE and 50% FALSE)\u003C/em>\u003C/li>\n\u003Cli>You rarely perform queries on this column\u003C/li>\n\u003Cli>The table is write-heavy \u003Cem>(more INSERT/UPDATE than SELECT)\u003C/em>\u003C/li>\n\u003C/ul>\n\u003Cpre class=\"shiki shiki-themes github-light github-dark\" style=\"background-color:light-dark(#fff, #24292e);--shiki-light-bg:#fff;--shiki-dark-bg:#24292e;color:light-dark(#24292e, #e1e4e8);--shiki-light:#24292e;--shiki-dark:#e1e4e8\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- SPRAWDZANIE użycia indeksów\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">SELECT\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    schemaname,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    tablename,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    indexname,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    idx_scan,  \u003C/span>\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- ile razy indeks został użyty\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    idx_tup_read,  \u003C/span>\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- ile wierszy odczytano przez indeks\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    idx_tup_fetch  \u003C/span>\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- ile wierszy zostało faktycznie pobranych\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">FROM\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> pg_stat_user_indexes\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">ORDER BY\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> idx_scan \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">ASC\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;  \u003C/span>\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- indeksy z najmniejszą liczbą użyć\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Jeśli idx_scan = 0, indeks nigdy nie był używany - możesz go usunąć\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">DROP\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> INDEX\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> idx_unused_index;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch2 id=\"table-partitioning-managing-huge-datasets\" tabindex=\"-1\">Table Partitioning — managing huge datasets\u003C/h2>\n\u003Cp>Partitioning is a technique of dividing one large table into smaller physical parts \u003Cem>(partitions)\u003C/em> that logically behave as a single table. It's like sorting documents into separate drawers according to criteria — it's easier to find what you're looking for.\u003C/p>\n\u003Ch3 id=\"when-is-it-worth-partitioning\" tabindex=\"-1\">When is it worth partitioning?\u003C/h3>\n\u003Cp>Partitioning makes sense when:\u003C/p>\n\u003Cul>\n\u003Cli>The table exceeds the server's RAM size \u003Cem>(e.g., a 100GB table with 32GB RAM)\u003C/em>\u003C/li>\n\u003Cli>You regularly delete old data \u003Cem>(e.g., logs older than 90 days)\u003C/em>\u003C/li>\n\u003Cli>Most queries concern a specific data range \u003Cem>(last month, specific region)\u003C/em>\u003C/li>\n\u003Cli>You want to move old data to slower storage\u003C/li>\n\u003C/ul>\n\u003Cp>Rule of thumb: if a table has more than several tens of millions of rows and is growing, consider partitioning.\u003C/p>\n\u003Ch3 id=\"range-partitioning-the-most-popular-choice\" tabindex=\"-1\">Range Partitioning — the most popular choice\u003C/h3>\n\u003Cp>Range partitioning divides data by a range of values — most often by date.\u003C/p>\n\u003Cpre class=\"shiki shiki-themes github-light github-dark\" style=\"background-color:light-dark(#fff, #24292e);--shiki-light-bg:#fff;--shiki-dark-bg:#24292e;color:light-dark(#24292e, #e1e4e8);--shiki-light:#24292e;--shiki-dark:#e1e4e8\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Tworzymy główną tabelę (parent table)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">CREATE\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> TABLE\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> events\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> (\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    id \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">BIGSERIAL\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    event_type \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">VARCHAR\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">50\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">NOT NULL\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    user_id \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">INTEGER\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> NOT NULL\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    event_data JSONB,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    created_at \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">TIMESTAMP\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> NOT NULL\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">PARTITION\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> BY\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> RANGE\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> (created_at);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Tworzymy partycje dla każdego miesiąca\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Partycja dla stycznia 2025\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">CREATE\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> TABLE\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> events_2025_01\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> PARTITION\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> OF events\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">    FOR\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> VALUES\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> FROM\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> (\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'2025-01-01'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">TO\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> (\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'2025-02-01'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Partycja dla lutego 2025\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">CREATE\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> TABLE\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> events_2025_02\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> PARTITION\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> OF events\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">    FOR\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> VALUES\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> FROM\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> (\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'2025-02-01'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">TO\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> (\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'2025-03-01'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Partycja dla marca 2025\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">CREATE\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> TABLE\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> events_2025_03\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> PARTITION\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> OF events\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">    FOR\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> VALUES\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> FROM\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> (\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'2025-03-01'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">TO\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> (\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'2025-04-01'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- UWAGA: Zakresy są [inclusive, exclusive), \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- czyli '2025-02-01' należy do partycji lutego, nie stycznia\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Dodajemy indeksy na każdą partycję\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">CREATE\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> INDEX\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> idx_events_2025_01_user\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> ON\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> events_2025_01(user_id);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">CREATE\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> INDEX\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> idx_events_2025_02_user\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> ON\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> events_2025_02(user_id);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">CREATE\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> INDEX\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> idx_events_2025_03_user\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> ON\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> events_2025_03(user_id);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\u003C/code>\u003C/pre>\n\u003Cp>When you execute a query, PostgreSQL automatically knows which partitions to search \u003Cem>(partition pruning)\u003C/em>:\u003C/p>\n\u003Cpre class=\"shiki shiki-themes github-light github-dark\" style=\"background-color:light-dark(#fff, #24292e);--shiki-light-bg:#fff;--shiki-dark-bg:#24292e;color:light-dark(#24292e, #e1e4e8);--shiki-light:#24292e;--shiki-dark:#e1e4e8\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- To zapytanie przeszuka TYLKO partycję luty 2025\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">SELECT\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> *\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> FROM\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> events \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">WHERE\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> created_at \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">BETWEEN\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> '2025-02-01'\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> AND\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> '2025-02-28'\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">  AND\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> user_id \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">=\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> 12345\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Explain pokaże Ci, które partycje są skanowane\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">EXPLAIN \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">SELECT\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> *\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> FROM\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> events \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">WHERE\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> created_at \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">BETWEEN\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> '2025-02-01'\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> AND\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> '2025-02-28'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch3 id=\"automating-partition-creation\" tabindex=\"-1\">Automating Partition Creation\u003C/h3>\n\u003Cp>Creating partitions manually is tedious. You can automate it with a function:\u003C/p>\n\u003Cpre class=\"shiki shiki-themes github-light github-dark\" style=\"background-color:light-dark(#fff, #24292e);--shiki-light-bg:#fff;--shiki-dark-bg:#24292e;color:light-dark(#24292e, #e1e4e8);--shiki-light:#24292e;--shiki-dark:#e1e4e8\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Funkcja tworząca partycje na przyszłe miesiące\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">CREATE OR REPLACE\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> FUNCTION\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> create_monthly_partitions\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    table_name \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">TEXT\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    months_ahead \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">INTEGER\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> DEFAULT\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> 3\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">RETURNS\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> VOID \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">AS\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> $$\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">DECLARE\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">    start_date\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> DATE\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    end_date \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">DATE\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    partition_name \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">TEXT\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    i \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">INTEGER\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">BEGIN\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">    -- Tworzymy partycje dla kolejnych miesięcy\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">    FOR\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> i \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">IN\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> 0\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">..months_ahead \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">LOOP\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">        start_date\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> :\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">=\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> DATE_TRUNC(\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'month'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">NOW\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">() \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">+\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> (i \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">||\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> ' months'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">)::INTERVAL);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">        end_date :\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">=\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> start_date\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> +\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> INTERVAL \u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'1 month'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">        partition_name :\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">=\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> table_name \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">||\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> '_'\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> ||\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> TO_CHAR(\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">start_date\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'YYYY_MM'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">        \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">        -- Sprawdzamy czy partycja już istnieje\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">        IF\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> NOT\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> EXISTS\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> (\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">            SELECT\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> 1\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> FROM\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> pg_tables \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">            WHERE\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> tablename \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">=\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> partition_name\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">        ) \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">THEN\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">            -- Tworzymy partycję\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">            EXECUTE\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> format\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">                'CREATE TABLE %I PARTITION OF %I FOR VALUES FROM (%L) TO (%L)'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">                partition_name,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">                table_name,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">                start_date\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">                end_date\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">            );\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">            \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">            -- Dodajemy indeksy\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">            EXECUTE\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> format\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">                'CREATE INDEX idx_%s_user ON %I(user_id)'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">                partition_name,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">                partition_name\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">            );\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">            \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">            RAISE NOTICE \u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'Created partition: %'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, partition_name;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">        END\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> IF\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">    END\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> LOOP\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">END\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">$$ \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">LANGUAGE\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> plpgsql;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Wywołanie funkcji\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">SELECT\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> create_monthly_partitions(\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'events'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">6\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);  \u003C/span>\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Tworzy partycje na 6 miesięcy do przodu\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\u003C/code>\u003C/pre>\n\u003Cp>You can add this function to \u003Ccode>cron\u003C/code> or Task Scheduler to run once a month.\u003C/p>\n\u003Ch3 id=\"deleting-old-data-instantly\" tabindex=\"-1\">Deleting old data — instantly\u003C/h3>\n\u003Cp>The biggest advantage of partitioning: you can delete millions of rows in a fraction of a second, simply by dropping an entire partition.\u003C/p>\n\u003Cpre class=\"shiki shiki-themes github-light github-dark\" style=\"background-color:light-dark(#fff, #24292e);--shiki-light-bg:#fff;--shiki-dark-bg:#24292e;color:light-dark(#24292e, #e1e4e8);--shiki-light:#24292e;--shiki-dark:#e1e4e8\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Zamiast tego (POWOLNE - może trwać godzinami):\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">DELETE\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> FROM\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> events \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">WHERE\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> created_at \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">&#x3C;\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> '2024-01-01'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;  \u003C/span>\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- ❌ Bardzo powolne!\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Zrób to (SZYBKIE - milisekundy):\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">DROP\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> TABLE\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> events_2024_01;  \u003C/span>\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- ✓ Błyskawiczne!\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Lub odłącz partycję zamiast usuwać (możesz ją później zarchiwizować):\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">ALTER\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> TABLE\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> events DETACH \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">PARTITION\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> events_2024_01;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Teraz events_2024_01 to osobna tabela, możesz ją wyeksportować lub usunąć później\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\u003C/code>\u003C/pre>\n\u003Cp>The difference? \u003Ccode>DELETE\u003C/code> has to scan the table, delete each row, update indexes, and run VACUUM. \u003Ccode>DROP TABLE\u003C/code> simply removes the entire file. That's the difference between hours and milliseconds.\u003C/p>\n\u003Ch3 id=\"list-partitioning-for-categories\" tabindex=\"-1\">List Partitioning — for categories\u003C/h3>\n\u003Cp>When your data has clear categories \u003Cem>(regions, statuses, types)\u003C/em>, use list partitioning.\u003C/p>\n\u003Cpre class=\"shiki shiki-themes github-light github-dark\" style=\"background-color:light-dark(#fff, #24292e);--shiki-light-bg:#fff;--shiki-dark-bg:#24292e;color:light-dark(#24292e, #e1e4e8);--shiki-light:#24292e;--shiki-dark:#e1e4e8\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Tabela zamówień partycjonowana po regionach\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">CREATE\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> TABLE\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> orders\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> (\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    id \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">BIGSERIAL\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    order_number \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">VARCHAR\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">50\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">NOT NULL\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    user_id \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">INTEGER\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> NOT NULL\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    region \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">VARCHAR\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">50\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">NOT NULL\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    total \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">DECIMAL\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">10\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">2\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">),\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    created_at \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">TIMESTAMP\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> DEFAULT\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> NOW\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">()\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">PARTITION\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> BY\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> LIST (region);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Partycja dla Europy\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">CREATE\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> TABLE\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> orders_europe\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> PARTITION\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> OF orders\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">    FOR\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> VALUES\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> IN\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> (\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'PL'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'DE'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'FR'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'UK'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'IT'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'ES'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Partycja dla Ameryki Północnej\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">CREATE\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> TABLE\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> orders_north_america\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> PARTITION\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> OF orders\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">    FOR\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> VALUES\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> IN\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> (\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'US'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'CA'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'MX'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Partycja dla Azji\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">CREATE\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> TABLE\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> orders_asia\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> PARTITION\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> OF orders\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">    FOR\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> VALUES\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> IN\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> (\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'JP'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'CN'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'IN'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'SG'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Default partition dla pozostałych\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">CREATE\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> TABLE\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> orders_other\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> PARTITION\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> OF orders \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">DEFAULT\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch3 id=\"hash-partitioning-even-data-distribution\" tabindex=\"-1\">Hash Partitioning — even data distribution\u003C/h3>\n\u003Cp>When you don't have a natural key for partitioning, use HASH. PostgreSQL will automatically distribute the data evenly.\u003C/p>\n\u003Cpre class=\"shiki shiki-themes github-light github-dark\" style=\"background-color:light-dark(#fff, #24292e);--shiki-light-bg:#fff;--shiki-dark-bg:#24292e;color:light-dark(#24292e, #e1e4e8);--shiki-light:#24292e;--shiki-dark:#e1e4e8\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Tabela użytkowników z partycjonowaniem hashowym po user_id\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">CREATE\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> TABLE\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> users_large\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> (\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    id \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">BIGSERIAL\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    email \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">VARCHAR\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">255\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">NOT NULL\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    username \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">VARCHAR\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">100\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">),\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    created_at \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">TIMESTAMP\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> DEFAULT\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> NOW\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">()\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">PARTITION\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> BY\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> HASH\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> (id);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Tworzymy 4 partycje (modulus = 4)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">CREATE\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> TABLE\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> users_large_0\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> PARTITION\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> OF users_large\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">    FOR\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> VALUES\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> WITH\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> (MODULUS \u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">4\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, REMAINDER \u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">0\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">CREATE\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> TABLE\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> users_large_1\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> PARTITION\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> OF users_large\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">    FOR\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> VALUES\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> WITH\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> (MODULUS \u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">4\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, REMAINDER \u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">1\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">CREATE\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> TABLE\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> users_large_2\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> PARTITION\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> OF users_large\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">    FOR\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> VALUES\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> WITH\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> (MODULUS \u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">4\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, REMAINDER \u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">2\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">CREATE\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> TABLE\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> users_large_3\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> PARTITION\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> OF users_large\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">    FOR\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> VALUES\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> WITH\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> (MODULUS \u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">4\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, REMAINDER \u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">3\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\u003C/code>\u003C/pre>\n\u003Cp>Hash partitioning has one drawback: you cannot easily delete old data because the data is scattered across all partitions. Use it when you only want to improve performance by evenly distributing data.\u003C/p>\n\u003Ch2 id=\"explain-analyze-your-best-friend\" tabindex=\"-1\">EXPLAIN ANALYZE — Your best friend\u003C/h2>\n\u003Cp>Before you start optimizing, you need to understand exactly what your query is doing. \u003Ccode>EXPLAIN ANALYZE\u003C/code> shows the query execution plan and actual times.\u003C/p>\n\u003Cpre class=\"shiki shiki-themes github-light github-dark\" style=\"background-color:light-dark(#fff, #24292e);--shiki-light-bg:#fff;--shiki-dark-bg:#24292e;color:light-dark(#24292e, #e1e4e8);--shiki-light:#24292e;--shiki-dark:#e1e4e8\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Podstawowe EXPLAIN\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">EXPLAIN \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">SELECT\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> *\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> FROM\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> users \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">WHERE\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> email \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">=\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> 'test@example.com'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- EXPLAIN ANALYZE - faktycznie wykonuje zapytanie i pokazuje rzeczywiste czasy\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">EXPLAIN ANALYZE \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">SELECT\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> *\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> FROM\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> users \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">WHERE\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> email \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">=\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> 'test@example.com'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Z dodatkowymi informacjami o bufferach\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">EXPLAIN (ANALYZE, BUFFERS) \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">SELECT\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> *\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> FROM\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> orders o\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">JOIN\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> users u \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">ON\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> o\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">.\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">user_id\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> =\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> u\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">.\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">id\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">WHERE\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> o\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">.\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">created_at\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> >\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> NOW\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">() \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">-\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> INTERVAL \u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'7 days'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\u003C/code>\u003C/pre>\n\u003Cp>What to look for in the result:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Seq Scan\u003C/strong> \u003Cem>(Sequential Scan)\u003C/em> — scanning the entire table, usually slow for large tables\u003C/li>\n\u003Cli>\u003Cstrong>Index Scan\u003C/strong> — uses an index, usually fast\u003C/li>\n\u003Cli>\u003Cstrong>Index Only Scan\u003C/strong> — fastest, all data from the index without accessing the table\u003C/li>\n\u003Cli>\u003Cstrong>Bitmap Heap Scan\u003C/strong> — uses multiple indexes at once\u003C/li>\n\u003Cli>\u003Cstrong>cost=0.00..100.00\u003C/strong> — estimated cost (lower = better)\u003C/li>\n\u003Cli>\u003Cstrong>actual time=0.050..1.234\u003C/strong> — actual time in milliseconds\u003C/li>\n\u003C/ul>\n\u003Cp>Example analysis:\u003C/p>\n\u003Cpre class=\"shiki shiki-themes github-light github-dark\" style=\"background-color:light-dark(#fff, #24292e);--shiki-light-bg:#fff;--shiki-dark-bg:#24292e;color:light-dark(#24292e, #e1e4e8);--shiki-light:#24292e;--shiki-dark:#e1e4e8\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">EXPLAIN (ANALYZE, BUFFERS) \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">SELECT\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> *\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> FROM\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> orders \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">WHERE\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> user_id \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">=\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> 12345\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> AND\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> status\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> =\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> 'pending'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Możliwy wynik:\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Seq Scan on orders  (cost=0.00..45000.00 rows=100 width=180) \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">--                     (actual time=0.123..234.567 rows=95 loops=1)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">--   Filter: (user_id = 12345 AND status::text = 'pending'::text)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">--   Rows Removed by Filter: 899905\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">--   Buffers: shared hit=23456\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Planning Time: 0.145 ms\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Execution Time: 234.789 ms\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- To pokazuje, że:\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- - Używa Seq Scan (źle!)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- - Sprawdził prawie milion wierszy, żeby znaleźć 95\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- - Potrzebny jest indeks!\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Dodajemy indeks:\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">CREATE\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> INDEX\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> idx_orders_user_status\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> ON\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> orders(user_id, \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">status\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Sprawdzamy ponownie:\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">EXPLAIN (ANALYZE, BUFFERS)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">SELECT\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> *\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> FROM\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> orders \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">WHERE\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> user_id \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">=\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> 12345\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> AND\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> status\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> =\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> 'pending'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Teraz:\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Index Scan using idx_orders_user_status on orders \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">--                     (cost=0.43..45.67 rows=95 width=180) \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">--                     (actual time=0.012..0.234 rows=95 loops=1)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">--   Index Cond: ((user_id = 12345) AND (status::text = 'pending'::text))\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">--   Buffers: shared hit=12\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Execution Time: 0.267 ms\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- 234ms -> 0.267ms. Prawie 1000x szybciej!\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch2 id=\"vacuum-and-analyze-maintaining-database-health\" tabindex=\"-1\">VACUUM and ANALYZE — maintaining database health\u003C/h2>\n\u003Cp>PostgreSQL uses MVCC \u003Cem>(Multi-Version Concurrency Control)\u003C/em>, which means old versions of rows are not deleted immediately. \u003Ccode>VACUUM\u003C/code> removes dead rows, and \u003Ccode>ANALYZE\u003C/code> updates statistics for the query optimizer.\u003C/p>\n\u003Cpre class=\"shiki shiki-themes github-light github-dark\" style=\"background-color:light-dark(#fff, #24292e);--shiki-light-bg:#fff;--shiki-dark-bg:#24292e;color:light-dark(#24292e, #e1e4e8);--shiki-light:#24292e;--shiki-dark:#e1e4e8\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Ręczne VACUUM dla konkretnej tabeli\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">VACUUM orders;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- VACUUM FULL - przepisuje całą tabelę (blokuje ją!)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">VACUUM FULL orders;  \u003C/span>\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- UWAGA: Nie używaj w produkcji bez przestoju!\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- ANALYZE aktualizuje statystyki\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">ANALYZE orders;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- VACUUM + ANALYZE razem\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">VACUUM ANALYZE orders;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Autovacuum - PostgreSQL robi to automatycznie\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Sprawdź ustawienia:\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">SHOW autovacuum;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">SHOW autovacuum_max_workers;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">SHOW autovacuum_naptime;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Sprawdź, kiedy ostatnio była vakuumowana tabela:\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">SELECT\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    schemaname, \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    relname, \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    last_vacuum, \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    last_autovacuum,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    n_dead_tup,  \u003C/span>\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- ilość martwych wierszy\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    n_live_tup   \u003C/span>\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- ilość żywych wierszy\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">FROM\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> pg_stat_user_tables\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">WHERE\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> relname \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">=\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> 'orders'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\u003C/code>\u003C/pre>\n\u003Cp>If \u003Ccode>n_dead_tup\u003C/code> is very high \u003Cem>(e.g., 20% of n_live_tup)\u003C/em>, manually run VACUUM.\u003C/p>\n\u003Ch2 id=\"redis-in-memory-cache-for-hot-data\" tabindex=\"-1\">Redis — in-memory cache for hot data\u003C/h2>\n\u003Cp>Even the best optimized PostgreSQL database won't beat the speed of data held in RAM. This is where Redis comes in — an in-memory key-value store that can handle millions of operations per second.\u003C/p>\n\u003Ch3 id=\"how-redis-works-and-why-its-so-fast\" tabindex=\"-1\">How Redis works and why it's so fast?\u003C/h3>\n\u003Cp>Redis stores all data in RAM, not on disk. This is a fundamental difference:\u003C/p>\n\u003Cul>\n\u003Cli>Read from SSD: about 10-20 ms\u003C/li>\n\u003Cli>Read from RAM: about 0.1 ms \u003Cem>(100 times faster)\u003C/em>\u003C/li>\n\u003Cli>Read from Redis: often below 1 ms, including network latency\u003C/li>\n\u003C/ul>\n\u003Cp>Redis is also single-threaded, which sounds like a limitation, but in reality it's an advantage. There are no expensive context switches, locks, or deadlocks. All operations are atomic and predictable.\u003C/p>\n\u003Cp>Additionally, Redis uses efficient in-memory data structures:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Strings\u003C/strong>: simple text or binary values\u003C/li>\n\u003Cli>\u003Cstrong>Hashes\u003C/strong>: key-value maps \u003Cem>(like JSON objects)\u003C/em>\u003C/li>\n\u003Cli>\u003Cstrong>Lists\u003C/strong>: ordered lists of elements\u003C/li>\n\u003Cli>\u003Cstrong>Sets\u003C/strong>: unordered collections of unique values\u003C/li>\n\u003Cli>\u003Cstrong>Sorted Sets\u003C/strong>: sets with assigned scores, automatically sorted\u003C/li>\n\u003C/ul>\n\u003Ch3 id=\"cache-aside-pattern-the-most-popular-strategy\" tabindex=\"-1\">Cache-Aside Pattern — the most popular strategy\u003C/h3>\n\u003Cp>Cache-Aside is a pattern where the application first checks the cache, and only if data is missing \u003Cem>(cache miss)\u003C/em> does it query the database.\u003C/p>\n\u003Cpre class=\"shiki shiki-themes github-light github-dark\" style=\"background-color:light-dark(#fff, #24292e);--shiki-light-bg:#fff;--shiki-dark-bg:#24292e;color:light-dark(#24292e, #e1e4e8);--shiki-light:#24292e;--shiki-dark:#e1e4e8\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">// Przykład w Node.js z użyciem biblioteki ioredis\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">const\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> Redis\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> =\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> require\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'ioredis'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">const\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> redis\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> =\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> new\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> Redis\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">({\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  host: \u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'localhost'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  port: \u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">6379\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  password: \u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'your-password'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,  \u003C/span>\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">// jeśli wymagane\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">});\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">// Funkcja pobierająca użytkownika\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">async\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> function\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> getUser\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#E36209, #FFAB70);--shiki-light:#E36209;--shiki-dark:#FFAB70\">userId\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">  const\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> cacheKey\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> =\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> `user:${\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">userId\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">}`\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">  // 1. Sprawdzamy cache\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">  let\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> user \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">=\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> await\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> redis.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">get\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(cacheKey);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">  if\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> (user) {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">    // Cache HIT - dane w Redis\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    console.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">log\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'Cache HIT'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">    return\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> JSON\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">parse\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(user);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  }\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">  // 2. Cache MISS - pobieramy z bazy danych\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  console.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">log\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'Cache MISS'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  user \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">=\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> await\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> db.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">query\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'SELECT * FROM users WHERE id = $1'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, [userId]);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">  if\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> (user) {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">    // 3. Zapisujemy do cache na 1 godzinę\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">    await\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> redis.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">setex\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">      cacheKey, \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">      3600\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,  \u003C/span>\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">// TTL w sekundach (1 godzina)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">      JSON\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">stringify\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(user)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    );\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  }\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">  return\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> user;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">// Przykład użycia:\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">const\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> user\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> =\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> await\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> getUser\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">12345\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\u003C/code>\u003C/pre>\n\u003Cp>Advantages of Cache-Aside:\u003C/p>\n\u003Cul>\n\u003Cli>Simple to implement\u003C/li>\n\u003Cli>Cache is populated on demand \u003Cem>(lazy loading)\u003C/em>\u003C/li>\n\u003Cli>Application works even if Redis is unavailable\u003C/li>\n\u003C/ul>\n\u003Cp>Disadvantages:\u003C/p>\n\u003Cul>\n\u003Cli>First query after cache expiration is slow\u003C/li>\n\u003Cli>Risk of stale data if data in the database changes\u003C/li>\n\u003C/ul>\n\u003Ch3 id=\"ttl-time-to-live-how-long-should-data-live-in-cache\" tabindex=\"-1\">TTL (Time To Live) — how long should data live in cache?\u003C/h3>\n\u003Cp>Setting the right TTL is a crucial decision. Too short TTL = frequent database queries. Too long TTL = stale data.\u003C/p>\n\u003Cpre class=\"shiki shiki-themes github-light github-dark\" style=\"background-color:light-dark(#fff, #24292e);--shiki-light-bg:#fff;--shiki-dark-bg:#24292e;color:light-dark(#24292e, #e1e4e8);--shiki-light:#24292e;--shiki-dark:#e1e4e8\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">// Różne TTL dla różnych typów danych\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">const\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> TTL\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> =\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  USER_PROFILE: \u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">3600\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,      \u003C/span>\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">// 1 godzina - dane użytkownika rzadko się zmieniają\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  PRODUCT_DETAILS: \u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">600\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,    \u003C/span>\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">// 10 minut - ceny mogą się zmieniać\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  SHOPPING_CART: \u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">1800\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,     \u003C/span>\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">// 30 minut - aktywny koszyk\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  SESSION: \u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">86400\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,          \u003C/span>\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">// 24 godziny - sesja użytkownika\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  RATE_LIMIT: \u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">60\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,          \u003C/span>\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">// 1 minuta - limity API\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">};\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">// Przykład: cachowanie danych produktu\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">async\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> function\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> getProduct\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#E36209, #FFAB70);--shiki-light:#E36209;--shiki-dark:#FFAB70\">productId\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">  const\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> cacheKey\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> =\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> `product:${\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">productId\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">}`\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">  let\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> product \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">=\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> await\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> redis.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">get\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(cacheKey);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">  if\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> (product) \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">return\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> JSON\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">parse\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(product);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  product \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">=\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> await\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> db.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">query\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'SELECT * FROM products WHERE id = $1'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, [productId]);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">  if\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> (product) {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">    await\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> redis.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">setex\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">      cacheKey,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">      TTL\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">.\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">PRODUCT_DETAILS\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">      JSON\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">stringify\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(product)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    );\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  }\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">  return\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> product;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch3 id=\"cache-invalidation-the-hardest-problem\" tabindex=\"-1\">Cache Invalidation — the hardest problem\u003C/h3>\n\u003Cp>Phil Karlton said: \u003Cem>&quot;There are only two hard things in Computer Science: cache invalidation and naming things&quot;\u003C/em>. Cache invalidation is indeed difficult.\u003C/p>\n\u003Cpre class=\"shiki shiki-themes github-light github-dark\" style=\"background-color:light-dark(#fff, #24292e);--shiki-light-bg:#fff;--shiki-dark-bg:#24292e;color:light-dark(#24292e, #e1e4e8);--shiki-light:#24292e;--shiki-dark:#e1e4e8\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">// Strategia 1: Usuwanie przy aktualizacji (Write-Through)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">async\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> function\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> updateUser\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#E36209, #FFAB70);--shiki-light:#E36209;--shiki-dark:#FFAB70\">userId\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:light-dark(#E36209, #FFAB70);--shiki-light:#E36209;--shiki-dark:#FFAB70\">userData\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">  // 1. Aktualizujemy bazę danych\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">  await\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> db.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">query\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">    'UPDATE users SET name = $1, email = $2 WHERE id = $3'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    [userData.name, userData.email, userId]\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  );\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">  // 2. Usuwamy stary cache\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">  await\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> redis.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">del\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">`user:${\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">userId\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">}`\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">  // Alternatywnie: od razu wstawiamy nowe dane do cache\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">  await\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> redis.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">setex\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">    `user:${\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">userId\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">}`\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">    TTL\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">.\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">USER_PROFILE\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">    JSON\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">stringify\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(userData)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  );\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">// Strategia 2: Cache tags - grupowe unieważnianie\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">async\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> function\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> createOrder\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#E36209, #FFAB70);--shiki-light:#E36209;--shiki-dark:#FFAB70\">userId\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:light-dark(#E36209, #FFAB70);--shiki-light:#E36209;--shiki-dark:#FFAB70\">orderData\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">  // Tworzymy zamówienie\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">  const\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> order\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> =\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> await\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> db.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">query\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'INSERT INTO orders ...'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">  // Unieważniamy wszystkie cache związane z użytkownikiem:\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">  // - lista zamówień użytkownika\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">  // - statystyki użytkownika\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">  // - dashboard użytkownika\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">  await\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> redis.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">del\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">    `user:${\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">userId\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">}:orders`\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">    `user:${\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">userId\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">}:stats`\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">    `user:${\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">userId\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">}:dashboard`\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  );\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">  return\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> order;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">// Strategia 3: Versioning - dodajemy wersję do klucza\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">async\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> function\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> getUserWithVersion\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#E36209, #FFAB70);--shiki-light:#E36209;--shiki-dark:#FFAB70\">userId\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">  // Wersja może być timestamp lub numer wersji\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">  const\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> version\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> =\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> await\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> redis.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">get\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">`user:${\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">userId\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">}:version`\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">||\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> '1'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">  const\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> cacheKey\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> =\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> `user:${\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">userId\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">}:v${\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">version\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">}`\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">  let\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> user \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">=\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> await\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> redis.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">get\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(cacheKey);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">  if\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> (user) \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">return\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> JSON\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">parse\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(user);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  user \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">=\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> await\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> db.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">query\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'SELECT * FROM users WHERE id = $1'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, [userId]);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">  await\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> redis.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">setex\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(cacheKey, \u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">TTL\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">.\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">USER_PROFILE\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">JSON\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">stringify\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(user));\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">  return\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> user;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">// Przy aktualizacji zwiększamy wersję\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">async\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> function\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> updateUserWithVersion\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#E36209, #FFAB70);--shiki-light:#E36209;--shiki-dark:#FFAB70\">userId\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:light-dark(#E36209, #FFAB70);--shiki-light:#E36209;--shiki-dark:#FFAB70\">userData\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">  await\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> db.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">query\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'UPDATE users SET ... WHERE id = $1'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, [userId]);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">  // Zwiększamy wersję - stary cache automatycznie staje się nieaktualny\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">  await\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> redis.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">incr\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">`user:${\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">userId\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">}:version`\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch3 id=\"cache-stampede-the-problem-of-cascading-queries\" tabindex=\"-1\">Cache Stampede — the problem of cascading queries\u003C/h3>\n\u003Cp>Imagine: the cache for a popular product expires exactly at 12:00. At that moment, 1000 requests simultaneously see no data in the cache, and all query the database. The server crashes.\u003C/p>\n\u003Cpre class=\"shiki shiki-themes github-light github-dark\" style=\"background-color:light-dark(#fff, #24292e);--shiki-light-bg:#fff;--shiki-dark-bg:#24292e;color:light-dark(#24292e, #e1e4e8);--shiki-light:#24292e;--shiki-dark:#e1e4e8\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">// Rozwiązanie: Lock pattern - tylko jeden request pobiera dane\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">const\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> crypto\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> =\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> require\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'crypto'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">async\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> function\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> getProductSafe\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#E36209, #FFAB70);--shiki-light:#E36209;--shiki-dark:#FFAB70\">productId\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">  const\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> cacheKey\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> =\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> `product:${\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">productId\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">}`\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">  const\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> lockKey\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> =\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> `lock:${\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">cacheKey\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">}`\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">  // 1. Sprawdzamy cache\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">  let\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> product \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">=\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> await\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> redis.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">get\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(cacheKey);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">  if\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> (product) \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">return\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> JSON\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">parse\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(product);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">  // 2. Próbujemy zdobyć lock (tylko jeden request to zrobi)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">  const\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> lockId\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> =\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> crypto.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">randomBytes\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">16\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">).\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">toString\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'hex'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">  const\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> acquired\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> =\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> await\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> redis.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">set\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    lockKey,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    lockId,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">    'NX'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,  \u003C/span>\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">// SET if Not eXists\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">    'EX'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">10\u003C/span>\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">  // wygasa po 10 sekundach\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  );\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">  if\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> (acquired) {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">    // Ten request zdobył lock - pobiera dane\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">    try\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">      product \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">=\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> await\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> db.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">query\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'SELECT * FROM products WHERE id = $1'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, [productId]);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">      \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">      if\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> (product) {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">        await\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> redis.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">setex\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(cacheKey, \u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">TTL\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">.\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">PRODUCT_DETAILS\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">JSON\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">stringify\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(product));\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">      }\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">      \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">      return\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> product;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    } \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">finally\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">      // Zwalniamy lock (tylko jeśli to nasz lock)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">      const\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> currentLock\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> =\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> await\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> redis.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">get\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(lockKey);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">      if\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> (currentLock \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">===\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> lockId) {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">        await\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> redis.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">del\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(lockKey);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">      }\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    }\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  } \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">else\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">    // Inny request już pobiera dane - czekamy chwilę i sprawdzamy ponownie cache\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">    await\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> new\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> Promise\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#E36209, #FFAB70);--shiki-light:#E36209;--shiki-dark:#FFAB70\">resolve\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> =>\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> setTimeout\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(resolve, \u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">100\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">));  \u003C/span>\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">// Czekamy 100ms\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">    return\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> getProductSafe\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(productId);  \u003C/span>\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">// Rekurencyjnie sprawdzamy ponownie\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  }\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch3 id=\"redis-hashes-memory-optimization\" tabindex=\"-1\">Redis Hashes — memory optimization\u003C/h3>\n\u003Cp>Instead of storing each field as a separate key, use a hash for objects.\u003C/p>\n\u003Cpre class=\"shiki shiki-themes github-light github-dark\" style=\"background-color:light-dark(#fff, #24292e);--shiki-light-bg:#fff;--shiki-dark-bg:#24292e;color:light-dark(#24292e, #e1e4e8);--shiki-light:#24292e;--shiki-dark:#e1e4e8\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">// NIEEFEKTYWNE - każde pole to osobny klucz:\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">await\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> redis.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">setex\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">`user:${\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">userId\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">}:name`\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">TTL\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">.\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">USER_PROFILE\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'John Doe'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">await\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> redis.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">setex\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">`user:${\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">userId\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">}:email`\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">TTL\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">.\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">USER_PROFILE\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'john@example.com'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">await\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> redis.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">setex\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">`user:${\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">userId\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">}:age`\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">TTL\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">.\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">USER_PROFILE\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'30'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">// 3 klucze, 3x overhead\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">// EFEKTYWNE - wszystko w jednym hash:\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">await\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> redis.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">hset\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">`user:${\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">userId\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">}`\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  name: \u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'John Doe'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  email: \u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'john@example.com'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  age: \u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'30'\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">});\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">await\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> redis.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">expire\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">`user:${\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">userId\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">}`\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">TTL\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">.\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">USER_PROFILE\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">// 1 klucz, mniejszy overhead\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">// Pobieranie całego obiektu:\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">const\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> user\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> =\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> await\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> redis.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">hgetall\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">`user:${\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">userId\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">}`\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">// Pobieranie pojedynczego pola:\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">const\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> email\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> =\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> await\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> redis.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">hget\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">`user:${\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">userId\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">}`\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'email'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">// Pobieranie wielu pól naraz:\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">const\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> [\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">name\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">age\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">] \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">=\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> await\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> redis.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">hmget\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">`user:${\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">userId\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">}`\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'name'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'age'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch3 id=\"redis-sets-caching-lists-and-relationships\" tabindex=\"-1\">Redis Sets — caching lists and relationships\u003C/h3>\n\u003Cp>Sets are excellent for storing lists of unique values, such as followers, product tags, or user permissions.\u003C/p>\n\u003Cpre class=\"shiki shiki-themes github-light github-dark\" style=\"background-color:light-dark(#fff, #24292e);--shiki-light-bg:#fff;--shiki-dark-bg:#24292e;color:light-dark(#24292e, #e1e4e8);--shiki-light:#24292e;--shiki-dark:#e1e4e8\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">// Przykład: followers użytkownika\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">async\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> function\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> followUser\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#E36209, #FFAB70);--shiki-light:#E36209;--shiki-dark:#FFAB70\">userId\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:light-dark(#E36209, #FFAB70);--shiki-light:#E36209;--shiki-dark:#FFAB70\">targetUserId\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">  // Dodajemy do bazy\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">  await\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> db.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">query\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'INSERT INTO follows (user_id, target_id) VALUES ($1, $2)'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    [userId, targetUserId]);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">  // Dodajemy do Redis Set\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">  await\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> redis.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">sadd\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">`user:${\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">targetUserId\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">}:followers`\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, userId);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">  await\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> redis.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">sadd\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">`user:${\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">userId\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">}:following`\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, targetUserId);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">// Sprawdzanie czy użytkownik followuje innego\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">async\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> function\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> isFollowing\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#E36209, #FFAB70);--shiki-light:#E36209;--shiki-dark:#FFAB70\">userId\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:light-dark(#E36209, #FFAB70);--shiki-light:#E36209;--shiki-dark:#FFAB70\">targetUserId\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">  const\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> following\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> =\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> await\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> redis.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">sismember\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">`user:${\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">userId\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">}:following`\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, targetUserId);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">  return\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> following \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">===\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> 1\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;  \u003C/span>\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">// 1 = true, 0 = false\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">// Liczba followers\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">async\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> function\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> getFollowerCount\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#E36209, #FFAB70);--shiki-light:#E36209;--shiki-dark:#FFAB70\">userId\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">  return\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> await\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> redis.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">scard\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">`user:${\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">userId\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">}:followers`\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">// Wspólni znajomi (przecięcie zbiorów)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">async\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> function\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> getMutualFollowers\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#E36209, #FFAB70);--shiki-light:#E36209;--shiki-dark:#FFAB70\">userId1\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:light-dark(#E36209, #FFAB70);--shiki-light:#E36209;--shiki-dark:#FFAB70\">userId2\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">  return\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> await\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> redis.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">sinter\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">    `user:${\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">userId1\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">}:followers`\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">    `user:${\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">userId2\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">}:followers`\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  );\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch3 id=\"sorted-sets-rankings-and-leaderboards\" tabindex=\"-1\">Sorted Sets — rankings and leaderboards\u003C/h3>\n\u003Cp>Sorted Sets store elements with an assigned score and automatically sort them.\u003C/p>\n\u003Cpre class=\"shiki shiki-themes github-light github-dark\" style=\"background-color:light-dark(#fff, #24292e);--shiki-light-bg:#fff;--shiki-dark-bg:#24292e;color:light-dark(#24292e, #e1e4e8);--shiki-light:#24292e;--shiki-dark:#e1e4e8\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">// Przykład: leaderboard gry\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">async\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> function\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> updatePlayerScore\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#E36209, #FFAB70);--shiki-light:#E36209;--shiki-dark:#FFAB70\">playerId\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:light-dark(#E36209, #FFAB70);--shiki-light:#E36209;--shiki-dark:#FFAB70\">score\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">  // Aktualizujemy wynik gracza\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">  await\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> redis.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">zadd\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'leaderboard'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, score, playerId);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">// Top 10 graczy\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">async\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> function\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> getTopPlayers\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#E36209, #FFAB70);--shiki-light:#E36209;--shiki-dark:#FFAB70\">limit\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> =\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> 10\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">  // ZREVRANGE - od największego do najmniejszego\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">  const\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> players\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> =\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> await\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> redis.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">zrevrange\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'leaderboard'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">0\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, limit \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">-\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> 1\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'WITHSCORES'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">  // Wynik: ['player1', '1000', 'player2', '950', ...]\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">  const\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> result\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> =\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> [];\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">  for\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> (\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">let\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> i \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">=\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> 0\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">; i \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">&#x3C;\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> players.\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">length\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">; i \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">+=\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> 2\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    result.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">push\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">({\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">      playerId: players[i],\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">      score: \u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">parseInt\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(players[i \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">+\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> 1\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">])\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    });\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  }\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">  return\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> result;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">// Pozycja gracza w rankingu\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">async\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> function\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> getPlayerRank\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#E36209, #FFAB70);--shiki-light:#E36209;--shiki-dark:#FFAB70\">playerId\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">  const\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> rank\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> =\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> await\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> redis.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">zrevrank\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'leaderboard'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, playerId);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">  return\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> rank \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">!==\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> null\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> ?\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> rank \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">+\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> 1\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> :\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> null\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;  \u003C/span>\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">// rank zaczyna się od 0\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">// Wynik gracza\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">async\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> function\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> getPlayerScore\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#E36209, #FFAB70);--shiki-light:#E36209;--shiki-dark:#FFAB70\">playerId\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">  return\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> await\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> redis.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">zscore\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'leaderboard'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, playerId);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">// Gracze w określonym przedziale punktów\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">async\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> function\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> getPlayersByScoreRange\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#E36209, #FFAB70);--shiki-light:#E36209;--shiki-dark:#FFAB70\">minScore\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:light-dark(#E36209, #FFAB70);--shiki-light:#E36209;--shiki-dark:#FFAB70\">maxScore\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">  return\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> await\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> redis.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">zrangebyscore\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'leaderboard'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, minScore, maxScore);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch2 id=\"monitoring-redis-performance\" tabindex=\"-1\">Monitoring Redis Performance\u003C/h2>\n\u003Cp>Redis provides built-in monitoring tools.\u003C/p>\n\u003Cpre class=\"shiki shiki-themes github-light github-dark\" style=\"background-color:light-dark(#fff, #24292e);--shiki-light-bg:#fff;--shiki-dark-bg:#24292e;color:light-dark(#24292e, #e1e4e8);--shiki-light:#24292e;--shiki-dark:#e1e4e8\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\"># INFO - kompletne statystyki\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">redis-cli\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> INFO\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\"># Najważniejsze metryki:\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">redis-cli\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> INFO\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> stats\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\"># - total_commands_processed: ile komend wykonano\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\"># - instantaneous_ops_per_sec: operacje na sekundę\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\"># - keyspace_hits: ile razy klucz był w cache\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\"># - keyspace_misses: ile razy klucza nie było\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\"># Hit ratio - procent trafień w cache\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">redis-cli\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> INFO\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> stats\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> |\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> grep\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> keyspace\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\"># Hit ratio = hits / (hits + misses)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\"># Dobry hit ratio to 80-90%+\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\"># SLOWLOG - powolne komendy (powyżej threshold)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">redis-cli\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> SLOWLOG\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> GET\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> 10\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\"># Używana pamięć\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">redis-cli\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> INFO\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> memory\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\"># - used_memory_human: ile pamięci używa Redis\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\"># - used_memory_peak_human: szczyt użycia pamięci\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\"># - maxmemory: limit pamięci\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\"># Aktywne połączenia\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">redis-cli\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> INFO\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> clients\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\"># - connected_clients: ile klientów połączonych\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch2 id=\"summary-from-theory-to-practice\" tabindex=\"-1\">Summary — from theory to practice\u003C/h2>\n\u003Cp>Database optimization is not an art for art's sake — these are concrete techniques that translate into faster applications and happier users.\u003C/p>\n\u003Cp>\u003Cstrong>PostgreSQL — key takeaways:\u003C/strong>\u003C/p>\n\u003Col>\n\u003Cli>\n\u003Cp>\u003Cstrong>Indexes are fundamental\u003C/strong>: B-Tree for most cases, GIN for JSONB, BRIN for huge time-series tables. Monitor index usage via \u003Ccode>pg_stat_user_indexes\u003C/code> and remove unused ones.\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Partitioning for large tables\u003C/strong>: RANGE for time-series data, LIST for categories, HASH for even distribution. Automate partition creation and use \u003Ccode>DROP TABLE\u003C/code> instead of \u003Ccode>DELETE\u003C/code> for deleting old data.\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>EXPLAIN ANALYZE is your compass\u003C/strong>: Always check the query plan before and after optimization. Look for Seq Scan on large tables — it often signals a missing index.\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>VACUUM and ANALYZE regularly\u003C/strong>: Autovacuum usually suffices, but for tables with many UPDATE/DELETE operations, it's sometimes worth running manually.\u003C/p>\n\u003C/li>\n\u003C/ol>\n\u003Cp>\u003Cstrong>Redis — key takeaways:\u003C/strong>\u003C/p>\n\u003Col>\n\u003Cli>\n\u003Cp>\u003Cstrong>Cache only hot data\u003C/strong>: Not everything needs to be cached. Cache frequently read data that is expensive to generate.\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Choose TTL appropriate for data characteristics\u003C/strong>: User sessions can live 24h, product prices only 10 minutes. Analyze your access patterns.\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Cache invalidation requires a strategy\u003C/strong>: Write-through for critical data, lazy loading for the rest. Avoid cache stampede by using a lock pattern.\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Use appropriate data structures\u003C/strong>: Hashes for objects, Sets for relationships, Sorted Sets for rankings. Each structure is optimized for a different use case.\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Monitor hit ratio\u003C/strong>: A good cache has an 80-90%+ hit ratio. If you have less, either you're not choosing what to cache well, or the TTL is too short.\u003C/p>\n\u003C/li>\n\u003C/ol>\n\u003Cp>Optimization is an iterative process. Start with measurements \u003Cem>(EXPLAIN ANALYZE, Redis monitoring)\u003C/em>, identify the bottleneck, apply the appropriate technique, and measure again. Sometimes an index is enough, sometimes you need partitioning, and sometimes Redis solves the problem in a second.\u003C/p>\n\u003Cp>Most importantly: don't optimize blindly. Always measure before and after changes. This is the only way to know if your optimization truly helped.\u003C/p>\n","\u003Ch2 id=\"optymalizacja-baz-danych-w-produkcji-postgresql-i-redis\" tabindex=\"-1\">Optymalizacja baz danych w produkcji: PostgreSQL i Redis\u003C/h2>\n\u003Cp>Wyobraź sobie, że Twoja aplikacja zaczyna zwalniać. Użytkownicy czekają sekundy zamiast milisekund na załadowanie danych. Dashboard admina czasami się zupełnie nie ładuje. Brzmi znajomo? W większości przypadków problem leży w bazie danych — źle zaprojektowane zapytania, brak indeksów, rosnące tabele bez partycjonowania. A gdy już dodasz odpowiednie indeksy, pojawia się kolejne wyzwanie: jak jeszcze bardziej przyspieszyć system?\u003C/p>\n\u003Cp>Odpowiedź na te pytania znajdziesz w dwóch narzędziach: optymalizacji PostgreSQL i inteligentnym cachowaniu z Redis. W tym artykule pokażę Ci konkretne techniki, które stosuję w produkcyjnych projektach obsługujących miliony requestów dziennie. Nie będzie teorii z podręcznika — tylko praktyczne przykłady z kodem i wyjaśnieniem, kiedy i dlaczego dane rozwiązanie działa.\u003C/p>\n\u003Cp>Rozpoczniemy od fundamentów optymalizacji PostgreSQL: indeksów, partycjonowania i innych sztuczek, które zmienią wolne zapytania w błyskawiczne. Następnie przejdziemy do Redis — pokażę Ci, jak działa ta technologia, dlaczego jest tak szybka i jak wykorzystać ją do stworzenia wydajnej warstwy cache dla gorących danych.\u003C/p>\n\u003Ch2 id=\"indeksy-w-postgresql-kiedy-i-jak-ich-uzywac\" tabindex=\"-1\">Indeksy w PostgreSQL — kiedy i jak ich używać\u003C/h2>\n\u003Cp>Indeksy to najważniejsze narzędzie optymalizacji baz danych. Zamiast skanować całą tabelę wiersz po wierszu \u003Cem>(sequential scan)\u003C/em>, PostgreSQL używa indeksu, aby znaleźć dokładnie te rekordy, których potrzebujesz. To jak różnica między czytaniem książki od deski do deski a skorzystaniem z indeksu na końcu książki.\u003C/p>\n\u003Ch3 id=\"b-tree-podstawowy-indeks-na-kazda-okazje\" tabindex=\"-1\">B-Tree — podstawowy indeks na każdą okazję\u003C/h3>\n\u003Cp>Indeks B-Tree to domyślny typ indeksu w PostgreSQL i najczęściej używany. Działa doskonale dla zapytań z operatorami porównania \u003Ccode>=\u003C/code>, \u003Ccode>&lt;\u003C/code>, \u003Ccode>&gt;\u003C/code>, \u003Ccode>&lt;=\u003C/code>, \u003Ccode>&gt;=\u003C/code>, \u003Ccode>BETWEEN\u003C/code> oraz \u003Ccode>ORDER BY\u003C/code>.\u003C/p>\n\u003Cpre class=\"shiki shiki-themes github-light github-dark\" style=\"background-color:light-dark(#fff, #24292e);--shiki-light-bg:#fff;--shiki-dark-bg:#24292e;color:light-dark(#24292e, #e1e4e8);--shiki-light:#24292e;--shiki-dark:#e1e4e8\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Przykład: tabela użytkowników\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">CREATE\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> TABLE\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> users\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> (\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    id \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">SERIAL\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> PRIMARY KEY\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,  \u003C/span>\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- PostgreSQL automatycznie tworzy indeks B-Tree na PRIMARY KEY\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    email \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">VARCHAR\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">255\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">NOT NULL\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    created_at \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">TIMESTAMP\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> DEFAULT\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> NOW\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(),\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    last_login \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">TIMESTAMP\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Dodajemy indeks na email - często wyszukujemy użytkowników po emailu\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">CREATE\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> INDEX\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> idx_users_email\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> ON\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> users(email);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Indeks na created_at - często filtrujemy użytkowników po dacie rejestracji\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">CREATE\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> INDEX\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> idx_users_created_at\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> ON\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> users(created_at);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\u003C/code>\u003C/pre>\n\u003Cp>Kiedy ten indeks nie pomoże? Gdy wybierasz większość wierszy z tabeli. Jeśli zapytanie zwraca 20-30% wszystkich rekordów, PostgreSQL prawdopodobnie zrobi \u003Ccode>sequential scan\u003C/code>, bo będzie to szybsze niż skakanie po indeksie.\u003C/p>\n\u003Ch3 id=\"indeksy-wielokolumnowe-porzadek-ma-znaczenie\" tabindex=\"-1\">Indeksy wielokolumnowe — porządek ma znaczenie\u003C/h3>\n\u003Cp>Możesz stworzyć indeks na kilku kolumnach jednocześnie. Bardzo ważne: kolejność kolumn ma kluczowe znaczenie.\u003C/p>\n\u003Cpre class=\"shiki shiki-themes github-light github-dark\" style=\"background-color:light-dark(#fff, #24292e);--shiki-light-bg:#fff;--shiki-dark-bg:#24292e;color:light-dark(#24292e, #e1e4e8);--shiki-light:#24292e;--shiki-dark:#e1e4e8\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Przykład: tabela zamówień\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">CREATE\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> TABLE\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> orders\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> (\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    id \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">SERIAL\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> PRIMARY KEY\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    user_id \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">INTEGER\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> NOT NULL\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">    status\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> VARCHAR\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">50\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">NOT NULL\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,  \u003C/span>\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- 'pending', 'paid', 'shipped', 'delivered'\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    created_at \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">TIMESTAMP\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> DEFAULT\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> NOW\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(),\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    total_amount \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">DECIMAL\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">10\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">2\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- DOBRZE: Najczęściej filtrujemy po user_id, a potem po status\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">CREATE\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> INDEX\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> idx_orders_user_status\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> ON\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> orders(user_id, \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">status\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- To zapytanie UŻYJE indeksu:\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">SELECT\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> *\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> FROM\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> orders \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">WHERE\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> user_id \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">=\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> 123\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> AND\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> status\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> =\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> 'pending'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- To zapytanie też UŻYJE indeksu (częściowo):\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">SELECT\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> *\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> FROM\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> orders \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">WHERE\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> user_id \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">=\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> 123\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- To zapytanie NIE UŻYJE indeksu (brak pierwszej kolumny z indeksu):\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">SELECT\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> *\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> FROM\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> orders \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">WHERE\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> status\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> =\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> 'pending'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\u003C/code>\u003C/pre>\n\u003Cp>Zasada jest prosta: indeks wielokolumnowy działa od lewej do prawej. Jeśli nie używasz pierwszej kolumny z indeksu w zapytaniu, indeks nie zadziała. Dla powyższego przykładu, jeśli często szukasz tylko po \u003Ccode>status\u003C/code>, potrzebujesz osobnego indeksu:\u003C/p>\n\u003Cpre class=\"shiki shiki-themes github-light github-dark\" style=\"background-color:light-dark(#fff, #24292e);--shiki-light-bg:#fff;--shiki-dark-bg:#24292e;color:light-dark(#24292e, #e1e4e8);--shiki-light:#24292e;--shiki-dark:#e1e4e8\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Dodatkowy indeks tylko na status\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">CREATE\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> INDEX\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> idx_orders_status\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> ON\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> orders(\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">status\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch3 id=\"indeksy-czesciowe-mniejsze-i-szybsze\" tabindex=\"-1\">Indeksy częściowe — mniejsze i szybsze\u003C/h3>\n\u003Cp>Jeśli interesuje Cię tylko podzbiór danych, stwórz indeks częściowy. Będzie mniejszy, szybszy do aktualizacji i równie wydajny dla określonych zapytań.\u003C/p>\n\u003Cpre class=\"shiki shiki-themes github-light github-dark\" style=\"background-color:light-dark(#fff, #24292e);--shiki-light-bg:#fff;--shiki-dark-bg:#24292e;color:light-dark(#24292e, #e1e4e8);--shiki-light:#24292e;--shiki-dark:#e1e4e8\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Indeks tylko na aktywne zamówienia (status != 'delivered')\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Te zamówienia stanowią zazwyczaj małą część tabeli\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">CREATE\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> INDEX\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> idx_orders_active\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> ON\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> orders(user_id, \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">status\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">WHERE\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> status\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> !=\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> 'delivered'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- To zapytanie użyje indeksu częściowego:\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">SELECT\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> *\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> FROM\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> orders \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">WHERE\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> user_id \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">=\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> 123\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> AND\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> status\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> =\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> 'pending'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Możemy stworzyć indeks tylko na zamówienia z ostatnich 30 dni\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">CREATE\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> INDEX\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> idx_orders_recent\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> ON\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> orders(created_at) \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">WHERE\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> created_at \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">>\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> NOW\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">() \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">-\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> INTERVAL \u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'30 days'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\u003C/code>\u003C/pre>\n\u003Cp>Dlaczego to ma sens? W typowej aplikacji e-commerce, 95% zamówień to te już zrealizowane \u003Ccode>(delivered)\u003C/code>. Potrzebujesz szybkiego dostępu do aktywnych zamówień. Indeks częściowy będzie 20 razy mniejszy i znacznie szybszy w aktualizacji.\u003C/p>\n\u003Ch3 id=\"gin-indeks-dla-jsonb-i-penotekstowego-wyszukiwania\" tabindex=\"-1\">GIN — indeks dla JSONB i pełnotekstowego wyszukiwania\u003C/h3>\n\u003Cp>Gdy przechowujesz dane w formacie JSONB lub potrzebujesz wyszukiwania pełnotekstowego, indeks B-Tree nie wystarczy. Użyj GIN \u003Cem>(Generalized Inverted Index)\u003C/em>.\u003C/p>\n\u003Cpre class=\"shiki shiki-themes github-light github-dark\" style=\"background-color:light-dark(#fff, #24292e);--shiki-light-bg:#fff;--shiki-dark-bg:#24292e;color:light-dark(#24292e, #e1e4e8);--shiki-light:#24292e;--shiki-dark:#e1e4e8\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Tabela produktów z dodatkowymi atrybutami w JSONB\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">CREATE\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> TABLE\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> products\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> (\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    id \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">SERIAL\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> PRIMARY KEY\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">    name\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> VARCHAR\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">255\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">NOT NULL\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    attributes JSONB  \u003C/span>\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- przykład: {\"color\": \"red\", \"size\": \"large\", \"tags\": [\"sale\", \"new\"]}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Indeks GIN na całej kolumnie JSONB\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">CREATE\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> INDEX\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> idx_products_attributes\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> ON\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> products \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">USING\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> GIN(attributes);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Teraz możesz szybko wyszukiwać po atrybutach:\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">SELECT\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> *\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> FROM\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> products \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">WHERE\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> attributes @\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">>\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> '{\"color\": \"red\"}'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Wyszukiwanie po zagnieżdżonych wartościach:\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">SELECT\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> *\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> FROM\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> products \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">WHERE\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> attributes @\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">>\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> '{\"tags\": [\"sale\"]}'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Operatory dla JSONB:\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- @> zawiera (contains)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- ? istnieje klucz\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- ?| istnieje którykolwiek z kluczy\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- ?&#x26; istnieją wszystkie klucze\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\u003C/code>\u003C/pre>\n\u003Cp>Przykład z pełnotekstowym wyszukiwaniem:\u003C/p>\n\u003Cpre class=\"shiki shiki-themes github-light github-dark\" style=\"background-color:light-dark(#fff, #24292e);--shiki-light-bg:#fff;--shiki-dark-bg:#24292e;color:light-dark(#24292e, #e1e4e8);--shiki-light:#24292e;--shiki-dark:#e1e4e8\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Dodajemy kolumnę z wektorem wyszukiwania\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">ALTER\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> TABLE\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> products \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">ADD\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> COLUMN search_vector tsvector;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Tworzymy GIN indeks na wektorze\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">CREATE\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> INDEX\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> idx_products_search\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> ON\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> products \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">USING\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> GIN(search_vector);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Aktualizujemy wektor przy każdej zmianie (możesz to zautomatyzować triggerem)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">UPDATE\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> products \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">SET\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> search_vector \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">=\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> to_tsvector(\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'english'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">name\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> ||\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> ' '\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> ||\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> COALESCE\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">description\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">''\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">));\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Szybkie wyszukiwanie pełnotekstowe:\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">SELECT\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> *\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> FROM\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> products \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">WHERE\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> search_vector @@ to_tsquery(\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'english'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'laptop &#x26; gaming'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch3 id=\"brin-oszczedny-indeks-dla-ogromnych-tabel\" tabindex=\"-1\">BRIN — oszczędny indeks dla ogromnych tabel\u003C/h3>\n\u003Cp>BRIN \u003Cem>(Block Range Index)\u003C/em> to indeks, który przechowuje tylko minimum i maksimum wartości dla bloków danych. Jest idealny dla bardzo dużych tabel z naturalnie uporządkowanymi danymi, jak logi czy dane time-series.\u003C/p>\n\u003Cpre class=\"shiki shiki-themes github-light github-dark\" style=\"background-color:light-dark(#fff, #24292e);--shiki-light-bg:#fff;--shiki-dark-bg:#24292e;color:light-dark(#24292e, #e1e4e8);--shiki-light:#24292e;--shiki-dark:#e1e4e8\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Tabela logów systemowych\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">CREATE\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> TABLE\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> system_logs\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> (\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    id \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">BIGSERIAL\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> PRIMARY KEY\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    log_time \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">TIMESTAMP\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> NOT NULL\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">    level\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> VARCHAR\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">20\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">),\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">    message\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> TEXT\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Zamiast gigantycznego B-Tree, używamy BRIN\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">CREATE\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> INDEX\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> idx_logs_time\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> ON\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> system_logs \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">USING\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> BRIN(log_time);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Zapytania po zakresach czasu będą bardzo szybkie:\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">SELECT\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> *\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> FROM\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> system_logs \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">WHERE\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> log_time \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">BETWEEN\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> '2025-11-01'\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> AND\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> '2025-11-30'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\u003C/code>\u003C/pre>\n\u003Cp>Zalety BRIN:\u003C/p>\n\u003Cul>\n\u003Cli>Indeks zajmuje 1000x mniej miejsca niż B-Tree\u003C/li>\n\u003Cli>Bardzo szybkie tworzenie i aktualizacja\u003C/li>\n\u003Cli>Doskonały dla danych wstawianych chronologicznie\u003C/li>\n\u003C/ul>\n\u003Cp>Wady:\u003C/p>\n\u003Cul>\n\u003Cli>Działa tylko dla naturalnie uporządkowanych danych\u003C/li>\n\u003Cli>Mniej precyzyjny niż B-Tree\u003C/li>\n\u003C/ul>\n\u003Ch3 id=\"kiedy-nie-tworzyc-indeksow\" tabindex=\"-1\">Kiedy NIE tworzyć indeksów?\u003C/h3>\n\u003Cp>Indeksy mają koszt — zajmują miejsce i spowalniają operacje \u003Ccode>INSERT\u003C/code>, \u003Ccode>UPDATE\u003C/code> i \u003Ccode>DELETE\u003C/code>. Nie twórz indeksu, gdy:\u003C/p>\n\u003Cul>\n\u003Cli>Tabela jest bardzo mała \u003Cem>(poniżej 1000 wierszy)\u003C/em> — sequential scan będzie szybszy\u003C/li>\n\u003Cli>Kolumna ma bardzo niską kardynalność \u003Cem>(np. kolumna boolean z 50% TRUE i 50% FALSE)\u003C/em>\u003C/li>\n\u003Cli>Rzadko wykonujesz zapytania po tej kolumnie\u003C/li>\n\u003Cli>Tabela jest write-heavy \u003Cem>(więcej INSERT/UPDATE niż SELECT)\u003C/em>\u003C/li>\n\u003C/ul>\n\u003Cpre class=\"shiki shiki-themes github-light github-dark\" style=\"background-color:light-dark(#fff, #24292e);--shiki-light-bg:#fff;--shiki-dark-bg:#24292e;color:light-dark(#24292e, #e1e4e8);--shiki-light:#24292e;--shiki-dark:#e1e4e8\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- SPRAWDZANIE użycia indeksów\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">SELECT\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    schemaname,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    tablename,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    indexname,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    idx_scan,  \u003C/span>\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- ile razy indeks został użyty\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    idx_tup_read,  \u003C/span>\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- ile wierszy odczytano przez indeks\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    idx_tup_fetch  \u003C/span>\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- ile wierszy zostało faktycznie pobranych\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">FROM\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> pg_stat_user_indexes\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">ORDER BY\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> idx_scan \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">ASC\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;  \u003C/span>\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- indeksy z najmniejszą liczbą użyć\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Jeśli idx_scan = 0, indeks nigdy nie był używany - możesz go usunąć\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">DROP\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> INDEX\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> idx_unused_index;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch2 id=\"partycjonowanie-tabel-zarzadzanie-ogromnymi-zbiorami-danych\" tabindex=\"-1\">Partycjonowanie tabel — zarządzanie ogromnymi zbiorami danych\u003C/h2>\n\u003Cp>Partycjonowanie to technika dzielenia jednej dużej tabeli na mniejsze fizyczne części \u003Cem>(partycje)\u003C/em>, które logicznie zachowują się jak jedna tabela. To jak segregowanie dokumentów do osobnych szuflad według kryteriów — łatwiej znaleźć to, czego szukasz.\u003C/p>\n\u003Ch3 id=\"kiedy-warto-partycjonowac\" tabindex=\"-1\">Kiedy warto partycjonować?\u003C/h3>\n\u003Cp>Partycjonowanie ma sens, gdy:\u003C/p>\n\u003Cul>\n\u003Cli>Tabela przekracza rozmiar RAM serwera \u003Cem>(np. tabela 100GB przy 32GB RAM)\u003C/em>\u003C/li>\n\u003Cli>Regularnie usuwasz stare dane \u003Cem>(np. logi starsze niż 90 dni)\u003C/em>\u003C/li>\n\u003Cli>Większość zapytań dotyczy określonego zakresu danych \u003Cem>(ostatni miesiąc, konkretny region)\u003C/em>\u003C/li>\n\u003Cli>Chcesz przenieść stare dane na wolniejsze nośniki\u003C/li>\n\u003C/ul>\n\u003Cp>Zasada kciuka: jeśli tabela ma więcej niż kilkadziesiąt milionów wierszy i rośnie, rozważ partycjonowanie.\u003C/p>\n\u003Ch3 id=\"partycjonowanie-zakresowe-range-najpopularniejszy-wybor\" tabindex=\"-1\">Partycjonowanie zakresowe (RANGE) — najpopularniejszy wybór\u003C/h3>\n\u003Cp>Partycjonowanie zakresowe dzieli dane według zakresu wartości — najczęściej daty.\u003C/p>\n\u003Cpre class=\"shiki shiki-themes github-light github-dark\" style=\"background-color:light-dark(#fff, #24292e);--shiki-light-bg:#fff;--shiki-dark-bg:#24292e;color:light-dark(#24292e, #e1e4e8);--shiki-light:#24292e;--shiki-dark:#e1e4e8\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Tworzymy główną tabelę (parent table)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">CREATE\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> TABLE\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> events\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> (\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    id \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">BIGSERIAL\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    event_type \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">VARCHAR\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">50\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">NOT NULL\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    user_id \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">INTEGER\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> NOT NULL\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    event_data JSONB,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    created_at \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">TIMESTAMP\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> NOT NULL\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">PARTITION\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> BY\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> RANGE\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> (created_at);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Tworzymy partycje dla każdego miesiąca\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Partycja dla stycznia 2025\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">CREATE\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> TABLE\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> events_2025_01\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> PARTITION\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> OF events\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">    FOR\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> VALUES\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> FROM\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> (\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'2025-01-01'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">TO\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> (\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'2025-02-01'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Partycja dla lutego 2025\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">CREATE\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> TABLE\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> events_2025_02\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> PARTITION\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> OF events\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">    FOR\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> VALUES\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> FROM\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> (\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'2025-02-01'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">TO\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> (\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'2025-03-01'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Partycja dla marca 2025\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">CREATE\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> TABLE\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> events_2025_03\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> PARTITION\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> OF events\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">    FOR\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> VALUES\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> FROM\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> (\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'2025-03-01'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">TO\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> (\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'2025-04-01'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- UWAGA: Zakresy są [inclusive, exclusive), \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- czyli '2025-02-01' należy do partycji lutego, nie stycznia\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Dodajemy indeksy na każdą partycję\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">CREATE\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> INDEX\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> idx_events_2025_01_user\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> ON\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> events_2025_01(user_id);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">CREATE\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> INDEX\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> idx_events_2025_02_user\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> ON\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> events_2025_02(user_id);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">CREATE\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> INDEX\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> idx_events_2025_03_user\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> ON\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> events_2025_03(user_id);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\u003C/code>\u003C/pre>\n\u003Cp>Gdy wykonujesz zapytanie, PostgreSQL automatycznie wie, które partycje musi przeszukać \u003Cem>(partition pruning)\u003C/em>:\u003C/p>\n\u003Cpre class=\"shiki shiki-themes github-light github-dark\" style=\"background-color:light-dark(#fff, #24292e);--shiki-light-bg:#fff;--shiki-dark-bg:#24292e;color:light-dark(#24292e, #e1e4e8);--shiki-light:#24292e;--shiki-dark:#e1e4e8\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- To zapytanie przeszuka TYLKO partycję luty 2025\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">SELECT\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> *\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> FROM\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> events \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">WHERE\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> created_at \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">BETWEEN\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> '2025-02-01'\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> AND\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> '2025-02-28'\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">  AND\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> user_id \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">=\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> 12345\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Explain pokaże Ci, które partycje są skanowane\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">EXPLAIN \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">SELECT\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> *\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> FROM\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> events \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">WHERE\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> created_at \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">BETWEEN\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> '2025-02-01'\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> AND\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> '2025-02-28'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch3 id=\"automatyczne-tworzenie-partycji\" tabindex=\"-1\">Automatyczne tworzenie partycji\u003C/h3>\n\u003Cp>Tworzenie partycji ręcznie jest męczące. Możesz to zautomatyzować funkcją:\u003C/p>\n\u003Cpre class=\"shiki shiki-themes github-light github-dark\" style=\"background-color:light-dark(#fff, #24292e);--shiki-light-bg:#fff;--shiki-dark-bg:#24292e;color:light-dark(#24292e, #e1e4e8);--shiki-light:#24292e;--shiki-dark:#e1e4e8\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Funkcja tworząca partycje na przyszłe miesiące\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">CREATE OR REPLACE\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> FUNCTION\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> create_monthly_partitions\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    table_name \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">TEXT\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    months_ahead \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">INTEGER\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> DEFAULT\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> 3\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">RETURNS\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> VOID \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">AS\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> $$\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">DECLARE\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">    start_date\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> DATE\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    end_date \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">DATE\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    partition_name \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">TEXT\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    i \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">INTEGER\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">BEGIN\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">    -- Tworzymy partycje dla kolejnych miesięcy\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">    FOR\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> i \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">IN\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> 0\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">..months_ahead \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">LOOP\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">        start_date\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> :\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">=\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> DATE_TRUNC(\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'month'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">NOW\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">() \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">+\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> (i \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">||\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> ' months'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">)::INTERVAL);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">        end_date :\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">=\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> start_date\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> +\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> INTERVAL \u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'1 month'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">        partition_name :\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">=\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> table_name \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">||\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> '_'\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> ||\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> TO_CHAR(\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">start_date\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'YYYY_MM'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">        \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">        -- Sprawdzamy czy partycja już istnieje\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">        IF\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> NOT\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> EXISTS\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> (\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">            SELECT\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> 1\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> FROM\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> pg_tables \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">            WHERE\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> tablename \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">=\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> partition_name\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">        ) \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">THEN\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">            -- Tworzymy partycję\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">            EXECUTE\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> format\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">                'CREATE TABLE %I PARTITION OF %I FOR VALUES FROM (%L) TO (%L)'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">                partition_name,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">                table_name,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">                start_date\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">                end_date\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">            );\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">            \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">            -- Dodajemy indeksy\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">            EXECUTE\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> format\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">                'CREATE INDEX idx_%s_user ON %I(user_id)'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">                partition_name,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">                partition_name\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">            );\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">            \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">            RAISE NOTICE \u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'Created partition: %'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, partition_name;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">        END\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> IF\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">    END\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> LOOP\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">END\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">$$ \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">LANGUAGE\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> plpgsql;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Wywołanie funkcji\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">SELECT\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> create_monthly_partitions(\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'events'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">6\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);  \u003C/span>\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Tworzy partycje na 6 miesięcy do przodu\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\u003C/code>\u003C/pre>\n\u003Cp>Możesz dodać tę funkcję do \u003Ccode>cron\u003C/code> lub Task Schedulera, żeby uruchamiała się raz w miesiącu.\u003C/p>\n\u003Ch3 id=\"usuwanie-starych-danych-byskawicznie\" tabindex=\"-1\">Usuwanie starych danych — błyskawicznie\u003C/h3>\n\u003Cp>Największa zaleta partycjonowania: możesz usunąć miliony wierszy w ułamku sekundy, po prostu usuwając całą partycję.\u003C/p>\n\u003Cpre class=\"shiki shiki-themes github-light github-dark\" style=\"background-color:light-dark(#fff, #24292e);--shiki-light-bg:#fff;--shiki-dark-bg:#24292e;color:light-dark(#24292e, #e1e4e8);--shiki-light:#24292e;--shiki-dark:#e1e4e8\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Zamiast tego (POWOLNE - może trwać godzinami):\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">DELETE\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> FROM\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> events \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">WHERE\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> created_at \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">&#x3C;\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> '2024-01-01'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;  \u003C/span>\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- ❌ Bardzo powolne!\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Zrób to (SZYBKIE - milisekundy):\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">DROP\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> TABLE\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> events_2024_01;  \u003C/span>\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- ✓ Błyskawiczne!\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Lub odłącz partycję zamiast usuwać (możesz ją później zarchiwizować):\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">ALTER\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> TABLE\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> events DETACH \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">PARTITION\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> events_2024_01;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Teraz events_2024_01 to osobna tabela, możesz ją wyeksportować lub usunąć później\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\u003C/code>\u003C/pre>\n\u003Cp>Różnica? \u003Ccode>DELETE\u003C/code> musi przeskanować tabelę, usunąć każdy wiersz, zaktualizować indeksy i uruchomić VACUUM. \u003Ccode>DROP TABLE\u003C/code> po prostu usuwa cały plik. To różnica między godzinami a milisekundami.\u003C/p>\n\u003Ch3 id=\"partycjonowanie-listowe-list-dla-kategorii\" tabindex=\"-1\">Partycjonowanie listowe (LIST) — dla kategorii\u003C/h3>\n\u003Cp>Gdy Twoje dane mają wyraźne kategorie \u003Cem>(regiony, statusy, typy)\u003C/em>, użyj partycjonowania listowego.\u003C/p>\n\u003Cpre class=\"shiki shiki-themes github-light github-dark\" style=\"background-color:light-dark(#fff, #24292e);--shiki-light-bg:#fff;--shiki-dark-bg:#24292e;color:light-dark(#24292e, #e1e4e8);--shiki-light:#24292e;--shiki-dark:#e1e4e8\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Tabela zamówień partycjonowana po regionach\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">CREATE\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> TABLE\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> orders\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> (\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    id \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">BIGSERIAL\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    order_number \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">VARCHAR\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">50\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">NOT NULL\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    user_id \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">INTEGER\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> NOT NULL\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    region \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">VARCHAR\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">50\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">NOT NULL\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    total \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">DECIMAL\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">10\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">2\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">),\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    created_at \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">TIMESTAMP\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> DEFAULT\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> NOW\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">()\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">PARTITION\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> BY\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> LIST (region);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Partycja dla Europy\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">CREATE\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> TABLE\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> orders_europe\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> PARTITION\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> OF orders\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">    FOR\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> VALUES\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> IN\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> (\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'PL'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'DE'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'FR'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'UK'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'IT'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'ES'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Partycja dla Ameryki Północnej\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">CREATE\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> TABLE\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> orders_north_america\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> PARTITION\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> OF orders\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">    FOR\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> VALUES\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> IN\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> (\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'US'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'CA'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'MX'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Partycja dla Azji\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">CREATE\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> TABLE\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> orders_asia\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> PARTITION\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> OF orders\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">    FOR\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> VALUES\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> IN\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> (\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'JP'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'CN'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'IN'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'SG'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Default partition dla pozostałych\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">CREATE\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> TABLE\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> orders_other\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> PARTITION\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> OF orders \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">DEFAULT\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch3 id=\"partycjonowanie-hashowe-hash-rownomierne-rozozenie-danych\" tabindex=\"-1\">Partycjonowanie hashowe (HASH) — równomierne rozłożenie danych\u003C/h3>\n\u003Cp>Gdy nie masz naturalnego klucza do partycjonowania, użyj HASH. PostgreSQL automatycznie rozłoży dane równomiernie.\u003C/p>\n\u003Cpre class=\"shiki shiki-themes github-light github-dark\" style=\"background-color:light-dark(#fff, #24292e);--shiki-light-bg:#fff;--shiki-dark-bg:#24292e;color:light-dark(#24292e, #e1e4e8);--shiki-light:#24292e;--shiki-dark:#e1e4e8\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Tabela użytkowników z partycjonowaniem hashowym po user_id\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">CREATE\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> TABLE\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> users_large\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> (\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    id \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">BIGSERIAL\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    email \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">VARCHAR\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">255\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">NOT NULL\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    username \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">VARCHAR\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">100\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">),\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    created_at \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">TIMESTAMP\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> DEFAULT\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> NOW\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">()\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">PARTITION\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> BY\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> HASH\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> (id);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Tworzymy 4 partycje (modulus = 4)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">CREATE\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> TABLE\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> users_large_0\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> PARTITION\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> OF users_large\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">    FOR\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> VALUES\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> WITH\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> (MODULUS \u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">4\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, REMAINDER \u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">0\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">CREATE\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> TABLE\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> users_large_1\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> PARTITION\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> OF users_large\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">    FOR\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> VALUES\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> WITH\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> (MODULUS \u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">4\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, REMAINDER \u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">1\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">CREATE\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> TABLE\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> users_large_2\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> PARTITION\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> OF users_large\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">    FOR\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> VALUES\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> WITH\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> (MODULUS \u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">4\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, REMAINDER \u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">2\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">CREATE\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> TABLE\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> users_large_3\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> PARTITION\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> OF users_large\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">    FOR\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> VALUES\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> WITH\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> (MODULUS \u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">4\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, REMAINDER \u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">3\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\u003C/code>\u003C/pre>\n\u003Cp>Partycjonowanie hashowe ma jedną wadę: nie możesz łatwo usuwać starych danych, bo dane są rozrzucone po wszystkich partycjach. Używaj go, gdy chcesz tylko poprawić wydajność poprzez równomierne rozłożenie danych.\u003C/p>\n\u003Ch2 id=\"explain-analyze-twoj-najlepszy-przyjaciel\" tabindex=\"-1\">EXPLAIN ANALYZE — Twój najlepszy przyjaciel\u003C/h2>\n\u003Cp>Zanim zaczniesz optymalizować, musisz zrozumieć, co dokładnie robi Twoje zapytanie. \u003Ccode>EXPLAIN ANALYZE\u003C/code> pokazuje plan wykonania zapytania i rzeczywiste czasy.\u003C/p>\n\u003Cpre class=\"shiki shiki-themes github-light github-dark\" style=\"background-color:light-dark(#fff, #24292e);--shiki-light-bg:#fff;--shiki-dark-bg:#24292e;color:light-dark(#24292e, #e1e4e8);--shiki-light:#24292e;--shiki-dark:#e1e4e8\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Podstawowe EXPLAIN\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">EXPLAIN \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">SELECT\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> *\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> FROM\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> users \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">WHERE\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> email \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">=\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> 'test@example.com'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- EXPLAIN ANALYZE - faktycznie wykonuje zapytanie i pokazuje rzeczywiste czasy\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">EXPLAIN ANALYZE \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">SELECT\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> *\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> FROM\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> users \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">WHERE\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> email \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">=\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> 'test@example.com'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Z dodatkowymi informacjami o bufferach\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">EXPLAIN (ANALYZE, BUFFERS) \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">SELECT\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> *\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> FROM\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> orders o\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">JOIN\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> users u \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">ON\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> o\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">.\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">user_id\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> =\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> u\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">.\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">id\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">WHERE\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> o\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">.\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">created_at\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> >\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> NOW\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">() \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">-\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> INTERVAL \u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'7 days'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\u003C/code>\u003C/pre>\n\u003Cp>Co szukać w wyniku:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Seq Scan\u003C/strong> \u003Cem>(Sequential Scan)\u003C/em> — skanowanie całej tabeli, zwykle powolne dla dużych tabel\u003C/li>\n\u003Cli>\u003Cstrong>Index Scan\u003C/strong> — używa indeksu, zazwyczaj szybkie\u003C/li>\n\u003Cli>\u003Cstrong>Index Only Scan\u003C/strong> — najszybszy, wszystkie dane z indeksu bez sięgania do tabeli\u003C/li>\n\u003Cli>\u003Cstrong>Bitmap Heap Scan\u003C/strong> — używa wielu indeksów naraz\u003C/li>\n\u003Cli>\u003Cstrong>cost=0.00..100.00\u003C/strong> — szacowany koszt (niższy = lepiej)\u003C/li>\n\u003Cli>\u003Cstrong>actual time=0.050..1.234\u003C/strong> — rzeczywisty czas w milisekundach\u003C/li>\n\u003C/ul>\n\u003Cp>Przykład analizy:\u003C/p>\n\u003Cpre class=\"shiki shiki-themes github-light github-dark\" style=\"background-color:light-dark(#fff, #24292e);--shiki-light-bg:#fff;--shiki-dark-bg:#24292e;color:light-dark(#24292e, #e1e4e8);--shiki-light:#24292e;--shiki-dark:#e1e4e8\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">EXPLAIN (ANALYZE, BUFFERS) \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">SELECT\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> *\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> FROM\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> orders \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">WHERE\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> user_id \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">=\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> 12345\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> AND\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> status\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> =\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> 'pending'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Możliwy wynik:\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Seq Scan on orders  (cost=0.00..45000.00 rows=100 width=180) \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">--                     (actual time=0.123..234.567 rows=95 loops=1)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">--   Filter: (user_id = 12345 AND status::text = 'pending'::text)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">--   Rows Removed by Filter: 899905\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">--   Buffers: shared hit=23456\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Planning Time: 0.145 ms\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Execution Time: 234.789 ms\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- To pokazuje, że:\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- - Używa Seq Scan (źle!)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- - Sprawdził prawie milion wierszy, żeby znaleźć 95\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- - Potrzebny jest indeks!\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Dodajemy indeks:\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">CREATE\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> INDEX\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> idx_orders_user_status\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> ON\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> orders(user_id, \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">status\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Sprawdzamy ponownie:\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">EXPLAIN (ANALYZE, BUFFERS)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">SELECT\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> *\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> FROM\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> orders \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">WHERE\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> user_id \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">=\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> 12345\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> AND\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> status\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> =\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> 'pending'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Teraz:\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Index Scan using idx_orders_user_status on orders \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">--                     (cost=0.43..45.67 rows=95 width=180) \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">--                     (actual time=0.012..0.234 rows=95 loops=1)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">--   Index Cond: ((user_id = 12345) AND (status::text = 'pending'::text))\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">--   Buffers: shared hit=12\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Execution Time: 0.267 ms\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- 234ms -> 0.267ms. Prawie 1000x szybciej!\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch2 id=\"vacuum-i-analyze-utrzymanie-zdrowia-bazy\" tabindex=\"-1\">VACUUM i ANALYZE — utrzymanie zdrowia bazy\u003C/h2>\n\u003Cp>PostgreSQL używa MVCC \u003Cem>(Multi-Version Concurrency Control)\u003C/em>, co oznacza, że stare wersje wierszy nie są od razu usuwane. \u003Ccode>VACUUM\u003C/code> usuwa martwe wiersze, a \u003Ccode>ANALYZE\u003C/code> aktualizuje statystyki dla optymalizatora zapytań.\u003C/p>\n\u003Cpre class=\"shiki shiki-themes github-light github-dark\" style=\"background-color:light-dark(#fff, #24292e);--shiki-light-bg:#fff;--shiki-dark-bg:#24292e;color:light-dark(#24292e, #e1e4e8);--shiki-light:#24292e;--shiki-dark:#e1e4e8\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Ręczne VACUUM dla konkretnej tabeli\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">VACUUM orders;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- VACUUM FULL - przepisuje całą tabelę (blokuje ją!)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">VACUUM FULL orders;  \u003C/span>\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- UWAGA: Nie używaj w produkcji bez przestoju!\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- ANALYZE aktualizuje statystyki\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">ANALYZE orders;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- VACUUM + ANALYZE razem\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">VACUUM ANALYZE orders;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Autovacuum - PostgreSQL robi to automatycznie\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Sprawdź ustawienia:\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">SHOW autovacuum;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">SHOW autovacuum_max_workers;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">SHOW autovacuum_naptime;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- Sprawdź, kiedy ostatnio była vakuumowana tabela:\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">SELECT\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    schemaname, \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    relname, \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    last_vacuum, \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    last_autovacuum,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    n_dead_tup,  \u003C/span>\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- ilość martwych wierszy\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    n_live_tup   \u003C/span>\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">-- ilość żywych wierszy\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">FROM\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> pg_stat_user_tables\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">WHERE\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> relname \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">=\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> 'orders'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\u003C/code>\u003C/pre>\n\u003Cp>Jeśli \u003Ccode>n_dead_tup\u003C/code> jest bardzo wysoki \u003Cem>(np. 20% n_live_tup)\u003C/em>, ręcznie uruchom VACUUM.\u003C/p>\n\u003Ch2 id=\"redis-in-memory-cache-dla-goracych-danych\" tabindex=\"-1\">Redis — in-memory cache dla gorących danych\u003C/h2>\n\u003Cp>Nawet najlepiej zoptymalizowana baza danych PostgreSQL nie pobije prędkości danych trzymanych w pamięci RAM. Tu wkracza Redis — in-memory key-value store, który może obsługiwać miliony operacji na sekundę.\u003C/p>\n\u003Ch3 id=\"jak-dziaa-redis-i-dlaczego-jest-tak-szybki\" tabindex=\"-1\">Jak działa Redis i dlaczego jest tak szybki?\u003C/h3>\n\u003Cp>Redis przechowuje wszystkie dane w pamięci RAM, a nie na dysku. To fundamentalna różnica:\u003C/p>\n\u003Cul>\n\u003Cli>Odczyt z dysku SSD: około 10-20 ms\u003C/li>\n\u003Cli>Odczyt z pamięci RAM: około 0.1 ms \u003Cem>(100 razy szybciej)\u003C/em>\u003C/li>\n\u003Cli>Odczyt z Redis: często poniżej 1 ms, włączając network latency\u003C/li>\n\u003C/ul>\n\u003Cp>Redis jest też single-threaded \u003Cem>(jeden wątek)\u003C/em>, co brzmi jak ograniczenie, ale w rzeczywistości to zaleta. Nie ma kosztownego przełączania kontekstu, lock-ów, czy deadlock-ów. Wszystkie operacje są atomowe i przewidywalne.\u003C/p>\n\u003Cp>Dodatkowo, Redis używa efektywnych struktur danych w pamięci:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Strings\u003C/strong>: proste wartości tekstowe lub binarne\u003C/li>\n\u003Cli>\u003Cstrong>Hashes\u003C/strong>: mapy klucz-wartość \u003Cem>(jak obiekty JSON)\u003C/em>\u003C/li>\n\u003Cli>\u003Cstrong>Lists\u003C/strong>: listy uporządkowanych elementów\u003C/li>\n\u003Cli>\u003Cstrong>Sets\u003C/strong>: nieuporządkowane zbiory unikalnych wartości\u003C/li>\n\u003Cli>\u003Cstrong>Sorted Sets\u003C/strong>: zbiory z przypisanymi scorami, automatycznie sortowane\u003C/li>\n\u003C/ul>\n\u003Ch3 id=\"cache-aside-pattern-najpopularniejsza-strategia\" tabindex=\"-1\">Cache-Aside Pattern — najpopularniejsza strategia\u003C/h3>\n\u003Cp>Cache-Aside to wzorzec, gdzie aplikacja najpierw sprawdza cache, a dopiero przy braku danych \u003Cem>(cache miss)\u003C/em> odpytuje bazę danych.\u003C/p>\n\u003Cpre class=\"shiki shiki-themes github-light github-dark\" style=\"background-color:light-dark(#fff, #24292e);--shiki-light-bg:#fff;--shiki-dark-bg:#24292e;color:light-dark(#24292e, #e1e4e8);--shiki-light:#24292e;--shiki-dark:#e1e4e8\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">// Przykład w Node.js z użyciem biblioteki ioredis\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">const\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> Redis\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> =\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> require\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'ioredis'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">const\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> redis\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> =\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> new\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> Redis\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">({\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  host: \u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'localhost'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  port: \u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">6379\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  password: \u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'your-password'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,  \u003C/span>\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">// jeśli wymagane\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">});\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">// Funkcja pobierająca użytkownika\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">async\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> function\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> getUser\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#E36209, #FFAB70);--shiki-light:#E36209;--shiki-dark:#FFAB70\">userId\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">  const\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> cacheKey\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> =\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> `user:${\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">userId\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">}`\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">  // 1. Sprawdzamy cache\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">  let\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> user \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">=\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> await\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> redis.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">get\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(cacheKey);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">  if\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> (user) {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">    // Cache HIT - dane w Redis\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    console.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">log\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'Cache HIT'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">    return\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> JSON\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">parse\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(user);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  }\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">  // 2. Cache MISS - pobieramy z bazy danych\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  console.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">log\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'Cache MISS'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  user \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">=\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> await\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> db.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">query\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'SELECT * FROM users WHERE id = $1'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, [userId]);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">  if\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> (user) {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">    // 3. Zapisujemy do cache na 1 godzinę\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">    await\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> redis.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">setex\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">      cacheKey, \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">      3600\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,  \u003C/span>\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">// TTL w sekundach (1 godzina)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">      JSON\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">stringify\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(user)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    );\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  }\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">  return\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> user;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">// Przykład użycia:\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">const\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> user\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> =\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> await\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> getUser\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">12345\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\u003C/code>\u003C/pre>\n\u003Cp>Zalety Cache-Aside:\u003C/p>\n\u003Cul>\n\u003Cli>Proste do zaimplementowania\u003C/li>\n\u003Cli>Cache jest zapełniany na żądanie \u003Cem>(lazy loading)\u003C/em>\u003C/li>\n\u003Cli>Aplikacja działa nawet gdy Redis jest niedostępny\u003C/li>\n\u003C/ul>\n\u003Cp>Wady:\u003C/p>\n\u003Cul>\n\u003Cli>Pierwsze zapytanie po wygaśnięciu cache jest wolne\u003C/li>\n\u003Cli>Ryzyko nieaktualnych danych, jeśli dane w bazie się zmienią\u003C/li>\n\u003C/ul>\n\u003Ch3 id=\"ttl-time-to-live-ile-dane-powinny-zyc-w-cache\" tabindex=\"-1\">TTL (Time To Live) — ile dane powinny żyć w cache?\u003C/h3>\n\u003Cp>Ustawienie odpowiedniego TTL to kluczowa decyzja. Za krótki TTL = częste odpytywanie bazy. Za długi TTL = nieaktualne dane.\u003C/p>\n\u003Cpre class=\"shiki shiki-themes github-light github-dark\" style=\"background-color:light-dark(#fff, #24292e);--shiki-light-bg:#fff;--shiki-dark-bg:#24292e;color:light-dark(#24292e, #e1e4e8);--shiki-light:#24292e;--shiki-dark:#e1e4e8\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">// Różne TTL dla różnych typów danych\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">const\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> TTL\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> =\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  USER_PROFILE: \u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">3600\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,      \u003C/span>\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">// 1 godzina - dane użytkownika rzadko się zmieniają\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  PRODUCT_DETAILS: \u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">600\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,    \u003C/span>\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">// 10 minut - ceny mogą się zmieniać\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  SHOPPING_CART: \u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">1800\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,     \u003C/span>\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">// 30 minut - aktywny koszyk\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  SESSION: \u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">86400\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,          \u003C/span>\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">// 24 godziny - sesja użytkownika\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  RATE_LIMIT: \u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">60\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,          \u003C/span>\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">// 1 minuta - limity API\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">};\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">// Przykład: cachowanie danych produktu\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">async\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> function\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> getProduct\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#E36209, #FFAB70);--shiki-light:#E36209;--shiki-dark:#FFAB70\">productId\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">  const\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> cacheKey\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> =\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> `product:${\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">productId\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">}`\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">  let\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> product \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">=\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> await\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> redis.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">get\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(cacheKey);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">  if\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> (product) \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">return\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> JSON\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">parse\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(product);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  product \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">=\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> await\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> db.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">query\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'SELECT * FROM products WHERE id = $1'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, [productId]);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">  if\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> (product) {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">    await\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> redis.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">setex\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">      cacheKey,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">      TTL\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">.\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">PRODUCT_DETAILS\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">      JSON\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">stringify\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(product)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    );\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  }\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">  return\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> product;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch3 id=\"uniewaznianie-cache-najtrudniejszy-problem\" tabindex=\"-1\">Unieważnianie cache — najtrudniejszy problem\u003C/h3>\n\u003Cp>Phil Karlton powiedział: \u003Cem>„There are only two hard things in Computer Science: cache invalidation and naming things&quot;\u003C/em>. Unieważnianie cache faktycznie jest trudne.\u003C/p>\n\u003Cpre class=\"shiki shiki-themes github-light github-dark\" style=\"background-color:light-dark(#fff, #24292e);--shiki-light-bg:#fff;--shiki-dark-bg:#24292e;color:light-dark(#24292e, #e1e4e8);--shiki-light:#24292e;--shiki-dark:#e1e4e8\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">// Strategia 1: Usuwanie przy aktualizacji (Write-Through)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">async\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> function\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> updateUser\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#E36209, #FFAB70);--shiki-light:#E36209;--shiki-dark:#FFAB70\">userId\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:light-dark(#E36209, #FFAB70);--shiki-light:#E36209;--shiki-dark:#FFAB70\">userData\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">  // 1. Aktualizujemy bazę danych\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">  await\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> db.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">query\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">    'UPDATE users SET name = $1, email = $2 WHERE id = $3'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    [userData.name, userData.email, userId]\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  );\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">  // 2. Usuwamy stary cache\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">  await\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> redis.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">del\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">`user:${\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">userId\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">}`\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">  // Alternatywnie: od razu wstawiamy nowe dane do cache\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">  await\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> redis.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">setex\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">    `user:${\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">userId\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">}`\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">    TTL\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">.\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">USER_PROFILE\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">    JSON\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">stringify\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(userData)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  );\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">// Strategia 2: Cache tags - grupowe unieważnianie\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">async\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> function\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> createOrder\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#E36209, #FFAB70);--shiki-light:#E36209;--shiki-dark:#FFAB70\">userId\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:light-dark(#E36209, #FFAB70);--shiki-light:#E36209;--shiki-dark:#FFAB70\">orderData\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">  // Tworzymy zamówienie\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">  const\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> order\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> =\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> await\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> db.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">query\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'INSERT INTO orders ...'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">  // Unieważniamy wszystkie cache związane z użytkownikiem:\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">  // - lista zamówień użytkownika\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">  // - statystyki użytkownika\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">  // - dashboard użytkownika\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">  await\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> redis.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">del\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">    `user:${\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">userId\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">}:orders`\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">    `user:${\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">userId\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">}:stats`\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">    `user:${\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">userId\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">}:dashboard`\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  );\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">  return\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> order;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">// Strategia 3: Versioning - dodajemy wersję do klucza\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">async\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> function\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> getUserWithVersion\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#E36209, #FFAB70);--shiki-light:#E36209;--shiki-dark:#FFAB70\">userId\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">  // Wersja może być timestamp lub numer wersji\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">  const\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> version\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> =\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> await\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> redis.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">get\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">`user:${\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">userId\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">}:version`\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">||\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> '1'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">  const\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> cacheKey\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> =\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> `user:${\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">userId\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">}:v${\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">version\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">}`\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">  let\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> user \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">=\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> await\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> redis.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">get\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(cacheKey);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">  if\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> (user) \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">return\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> JSON\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">parse\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(user);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  user \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">=\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> await\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> db.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">query\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'SELECT * FROM users WHERE id = $1'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, [userId]);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">  await\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> redis.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">setex\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(cacheKey, \u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">TTL\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">.\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">USER_PROFILE\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">JSON\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">stringify\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(user));\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">  return\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> user;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">// Przy aktualizacji zwiększamy wersję\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">async\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> function\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> updateUserWithVersion\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#E36209, #FFAB70);--shiki-light:#E36209;--shiki-dark:#FFAB70\">userId\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:light-dark(#E36209, #FFAB70);--shiki-light:#E36209;--shiki-dark:#FFAB70\">userData\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">  await\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> db.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">query\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'UPDATE users SET ... WHERE id = $1'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, [userId]);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">  // Zwiększamy wersję - stary cache automatycznie staje się nieaktualny\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">  await\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> redis.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">incr\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">`user:${\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">userId\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">}:version`\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch3 id=\"cache-stampede-problem-lawinowego-odpytywania\" tabindex=\"-1\">Cache Stampede — problem lawinowego odpytywania\u003C/h3>\n\u003Cp>Wyobraź sobie: cache dla popularnego produktu wygasa dokładnie o 12:00. W tym momencie 1000 requestów jednocześnie widzi brak danych w cache i wszystkie odpytują bazę danych. Serwer pada.\u003C/p>\n\u003Cpre class=\"shiki shiki-themes github-light github-dark\" style=\"background-color:light-dark(#fff, #24292e);--shiki-light-bg:#fff;--shiki-dark-bg:#24292e;color:light-dark(#24292e, #e1e4e8);--shiki-light:#24292e;--shiki-dark:#e1e4e8\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">// Rozwiązanie: Lock pattern - tylko jeden request pobiera dane\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">const\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> crypto\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> =\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> require\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'crypto'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">async\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> function\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> getProductSafe\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#E36209, #FFAB70);--shiki-light:#E36209;--shiki-dark:#FFAB70\">productId\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">  const\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> cacheKey\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> =\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> `product:${\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">productId\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">}`\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">  const\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> lockKey\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> =\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> `lock:${\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">cacheKey\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">}`\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">  // 1. Sprawdzamy cache\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">  let\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> product \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">=\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> await\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> redis.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">get\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(cacheKey);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">  if\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> (product) \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">return\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> JSON\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">parse\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(product);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">  // 2. Próbujemy zdobyć lock (tylko jeden request to zrobi)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">  const\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> lockId\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> =\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> crypto.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">randomBytes\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">16\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">).\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">toString\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'hex'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">  const\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> acquired\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> =\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> await\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> redis.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">set\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    lockKey,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    lockId,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">    'NX'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,  \u003C/span>\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">// SET if Not eXists\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">    'EX'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">10\u003C/span>\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">  // wygasa po 10 sekundach\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  );\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">  if\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> (acquired) {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">    // Ten request zdobył lock - pobiera dane\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">    try\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">      product \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">=\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> await\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> db.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">query\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'SELECT * FROM products WHERE id = $1'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, [productId]);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">      \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">      if\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> (product) {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">        await\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> redis.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">setex\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(cacheKey, \u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">TTL\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">.\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">PRODUCT_DETAILS\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">JSON\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">stringify\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(product));\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">      }\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">      \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">      return\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> product;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    } \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">finally\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">      // Zwalniamy lock (tylko jeśli to nasz lock)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">      const\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> currentLock\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> =\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> await\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> redis.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">get\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(lockKey);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">      if\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> (currentLock \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">===\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> lockId) {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">        await\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> redis.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">del\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(lockKey);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">      }\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    }\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  } \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">else\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">    // Inny request już pobiera dane - czekamy chwilę i sprawdzamy ponownie cache\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">    await\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> new\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> Promise\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#E36209, #FFAB70);--shiki-light:#E36209;--shiki-dark:#FFAB70\">resolve\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> =>\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> setTimeout\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(resolve, \u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">100\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">));  \u003C/span>\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">// Czekamy 100ms\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">    return\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> getProductSafe\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(productId);  \u003C/span>\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">// Rekurencyjnie sprawdzamy ponownie\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  }\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch3 id=\"redis-hashes-optymalizacja-pamieci\" tabindex=\"-1\">Redis Hashes — optymalizacja pamięci\u003C/h3>\n\u003Cp>Zamiast przechowywać każde pole jako osobny klucz, użyj hash dla obiektów.\u003C/p>\n\u003Cpre class=\"shiki shiki-themes github-light github-dark\" style=\"background-color:light-dark(#fff, #24292e);--shiki-light-bg:#fff;--shiki-dark-bg:#24292e;color:light-dark(#24292e, #e1e4e8);--shiki-light:#24292e;--shiki-dark:#e1e4e8\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">// NIEEFEKTYWNE - każde pole to osobny klucz:\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">await\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> redis.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">setex\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">`user:${\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">userId\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">}:name`\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">TTL\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">.\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">USER_PROFILE\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'John Doe'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">await\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> redis.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">setex\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">`user:${\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">userId\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">}:email`\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">TTL\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">.\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">USER_PROFILE\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'john@example.com'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">await\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> redis.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">setex\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">`user:${\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">userId\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">}:age`\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">TTL\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">.\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">USER_PROFILE\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'30'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">// 3 klucze, 3x overhead\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">// EFEKTYWNE - wszystko w jednym hash:\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">await\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> redis.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">hset\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">`user:${\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">userId\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">}`\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  name: \u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'John Doe'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  email: \u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'john@example.com'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  age: \u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'30'\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">});\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">await\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> redis.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">expire\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">`user:${\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">userId\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">}`\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">TTL\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">.\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">USER_PROFILE\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">// 1 klucz, mniejszy overhead\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">// Pobieranie całego obiektu:\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">const\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> user\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> =\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> await\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> redis.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">hgetall\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">`user:${\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">userId\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">}`\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">// Pobieranie pojedynczego pola:\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">const\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> email\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> =\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> await\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> redis.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">hget\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">`user:${\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">userId\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">}`\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'email'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">// Pobieranie wielu pól naraz:\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">const\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> [\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">name\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">age\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">] \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">=\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> await\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> redis.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">hmget\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">`user:${\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">userId\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">}`\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'name'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'age'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch3 id=\"redis-sets-cachowanie-list-i-relacji\" tabindex=\"-1\">Redis Sets — cachowanie list i relacji\u003C/h3>\n\u003Cp>Sets są doskonałe do przechowywania list unikalnych wartości, jak followers, tagi produktu czy permissions użytkownika.\u003C/p>\n\u003Cpre class=\"shiki shiki-themes github-light github-dark\" style=\"background-color:light-dark(#fff, #24292e);--shiki-light-bg:#fff;--shiki-dark-bg:#24292e;color:light-dark(#24292e, #e1e4e8);--shiki-light:#24292e;--shiki-dark:#e1e4e8\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">// Przykład: followers użytkownika\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">async\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> function\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> followUser\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#E36209, #FFAB70);--shiki-light:#E36209;--shiki-dark:#FFAB70\">userId\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:light-dark(#E36209, #FFAB70);--shiki-light:#E36209;--shiki-dark:#FFAB70\">targetUserId\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">  // Dodajemy do bazy\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">  await\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> db.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">query\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'INSERT INTO follows (user_id, target_id) VALUES ($1, $2)'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    [userId, targetUserId]);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">  // Dodajemy do Redis Set\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">  await\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> redis.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">sadd\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">`user:${\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">targetUserId\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">}:followers`\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, userId);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">  await\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> redis.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">sadd\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">`user:${\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">userId\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">}:following`\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, targetUserId);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">// Sprawdzanie czy użytkownik followuje innego\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">async\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> function\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> isFollowing\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#E36209, #FFAB70);--shiki-light:#E36209;--shiki-dark:#FFAB70\">userId\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:light-dark(#E36209, #FFAB70);--shiki-light:#E36209;--shiki-dark:#FFAB70\">targetUserId\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">  const\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> following\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> =\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> await\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> redis.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">sismember\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">`user:${\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">userId\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">}:following`\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, targetUserId);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">  return\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> following \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">===\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> 1\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;  \u003C/span>\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">// 1 = true, 0 = false\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">// Liczba followers\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">async\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> function\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> getFollowerCount\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#E36209, #FFAB70);--shiki-light:#E36209;--shiki-dark:#FFAB70\">userId\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">  return\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> await\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> redis.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">scard\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">`user:${\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">userId\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">}:followers`\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">// Wspólni znajomi (przecięcie zbiorów)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">async\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> function\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> getMutualFollowers\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#E36209, #FFAB70);--shiki-light:#E36209;--shiki-dark:#FFAB70\">userId1\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:light-dark(#E36209, #FFAB70);--shiki-light:#E36209;--shiki-dark:#FFAB70\">userId2\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">  return\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> await\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> redis.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">sinter\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">    `user:${\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">userId1\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">}:followers`\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">    `user:${\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">userId2\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">}:followers`\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  );\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch3 id=\"sorted-sets-rankingi-i-leaderboards\" tabindex=\"-1\">Sorted Sets — rankingi i leaderboards\u003C/h3>\n\u003Cp>Sorted Sets przechowują elementy z przypisanym wynikiem \u003Cem>(score)\u003C/em> i automatycznie je sortują.\u003C/p>\n\u003Cpre class=\"shiki shiki-themes github-light github-dark\" style=\"background-color:light-dark(#fff, #24292e);--shiki-light-bg:#fff;--shiki-dark-bg:#24292e;color:light-dark(#24292e, #e1e4e8);--shiki-light:#24292e;--shiki-dark:#e1e4e8\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">// Przykład: leaderboard gry\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">async\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> function\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> updatePlayerScore\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#E36209, #FFAB70);--shiki-light:#E36209;--shiki-dark:#FFAB70\">playerId\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:light-dark(#E36209, #FFAB70);--shiki-light:#E36209;--shiki-dark:#FFAB70\">score\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">  // Aktualizujemy wynik gracza\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">  await\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> redis.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">zadd\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'leaderboard'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, score, playerId);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">// Top 10 graczy\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">async\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> function\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> getTopPlayers\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#E36209, #FFAB70);--shiki-light:#E36209;--shiki-dark:#FFAB70\">limit\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> =\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> 10\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">  // ZREVRANGE - od największego do najmniejszego\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">  const\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> players\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> =\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> await\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> redis.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">zrevrange\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'leaderboard'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">0\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, limit \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">-\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> 1\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'WITHSCORES'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  \u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">  // Wynik: ['player1', '1000', 'player2', '950', ...]\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">  const\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> result\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> =\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> [];\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">  for\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> (\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">let\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> i \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">=\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> 0\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">; i \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">&#x3C;\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> players.\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\">length\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">; i \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">+=\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> 2\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    result.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">push\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">({\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">      playerId: players[i],\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">      score: \u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">parseInt\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(players[i \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">+\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> 1\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">])\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    });\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  }\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">  return\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> result;\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">// Pozycja gracza w rankingu\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">async\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> function\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> getPlayerRank\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#E36209, #FFAB70);--shiki-light:#E36209;--shiki-dark:#FFAB70\">playerId\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">  const\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> rank\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> =\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> await\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> redis.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">zrevrank\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'leaderboard'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, playerId);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">  return\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> rank \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">!==\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> null\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> ?\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> rank \u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">+\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> 1\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> :\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> null\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;  \u003C/span>\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">// rank zaczyna się od 0\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">// Wynik gracza\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">async\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> function\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> getPlayerScore\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#E36209, #FFAB70);--shiki-light:#E36209;--shiki-dark:#FFAB70\">playerId\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">  return\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> await\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> redis.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">zscore\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'leaderboard'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, playerId);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\">// Gracze w określonym przedziale punktów\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">async\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> function\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> getPlayersByScoreRange\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#E36209, #FFAB70);--shiki-light:#E36209;--shiki-dark:#FFAB70\">minScore\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, \u003C/span>\u003Cspan style=\"color:light-dark(#E36209, #FFAB70);--shiki-light:#E36209;--shiki-dark:#FFAB70\">maxScore\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) {\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\">  return\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> await\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> redis.\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">zrangebyscore\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'leaderboard'\u003C/span>\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, minScore, maxScore);\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#24292E, #E1E4E8);--shiki-light:#24292E;--shiki-dark:#E1E4E8\">}\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch2 id=\"monitorowanie-wydajnosci-redis\" tabindex=\"-1\">Monitorowanie wydajności Redis\u003C/h2>\n\u003Cp>Redis dostarcza wbudowane narzędzia do monitorowania.\u003C/p>\n\u003Cpre class=\"shiki shiki-themes github-light github-dark\" style=\"background-color:light-dark(#fff, #24292e);--shiki-light-bg:#fff;--shiki-dark-bg:#24292e;color:light-dark(#24292e, #e1e4e8);--shiki-light:#24292e;--shiki-dark:#e1e4e8\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\"># INFO - kompletne statystyki\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">redis-cli\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> INFO\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\"># Najważniejsze metryki:\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">redis-cli\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> INFO\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> stats\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\"># - total_commands_processed: ile komend wykonano\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\"># - instantaneous_ops_per_sec: operacje na sekundę\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\"># - keyspace_hits: ile razy klucz był w cache\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\"># - keyspace_misses: ile razy klucza nie było\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\"># Hit ratio - procent trafień w cache\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">redis-cli\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> INFO\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> stats\u003C/span>\u003Cspan style=\"color:light-dark(#D73A49, #F97583);--shiki-light:#D73A49;--shiki-dark:#F97583\"> |\u003C/span>\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> grep\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> keyspace\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\"># Hit ratio = hits / (hits + misses)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\"># Dobry hit ratio to 80-90%+\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\"># SLOWLOG - powolne komendy (powyżej threshold)\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">redis-cli\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> SLOWLOG\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> GET\u003C/span>\u003Cspan style=\"color:light-dark(#005CC5, #79B8FF);--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> 10\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\"># Używana pamięć\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">redis-cli\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> INFO\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> memory\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\"># - used_memory_human: ile pamięci używa Redis\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\"># - used_memory_peak_human: szczyt użycia pamięci\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\"># - maxmemory: limit pamięci\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\"># Aktywne połączenia\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6F42C1, #B392F0);--shiki-light:#6F42C1;--shiki-dark:#B392F0\">redis-cli\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> INFO\u003C/span>\u003Cspan style=\"color:light-dark(#032F62, #9ECBFF);--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> clients\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:light-dark(#6A737D, #6A737D);--shiki-light:#6A737D;--shiki-dark:#6A737D\"># - connected_clients: ile klientów połączonych\u003C/span>\u003C/span>\n\u003Cspan class=\"line\">\u003C/span>\u003C/code>\u003C/pre>\n\u003Ch2 id=\"podsumowanie-od-teorii-do-praktyki\" tabindex=\"-1\">Podsumowanie — od teorii do praktyki\u003C/h2>\n\u003Cp>Optymalizacja baz danych to nie sztuka dla sztuki — to konkretne techniki, które przekładają się na szybsze aplikacje i szczęśliwszych użytkowników.\u003C/p>\n\u003Cp>\u003Cstrong>PostgreSQL — kluczowe wnioski:\u003C/strong>\u003C/p>\n\u003Col>\n\u003Cli>\n\u003Cp>\u003Cstrong>Indeksy to fundament\u003C/strong>: B-Tree dla większości przypadków, GIN dla JSONB, BRIN dla ogromnych tabel czasowych. Monitoruj użycie indeksów przez \u003Ccode>pg_stat_user_indexes\u003C/code> i usuwaj niewykorzystywane.\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Partycjonowanie dla dużych tabel\u003C/strong>: RANGE dla danych czasowych, LIST dla kategorii, HASH dla równomiernego rozłożenia. Automatyzuj tworzenie partycji i korzystaj z \u003Ccode>DROP TABLE\u003C/code> zamiast \u003Ccode>DELETE\u003C/code> dla usuwania starych danych.\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>EXPLAIN ANALYZE to Twój kompas\u003C/strong>: Zawsze sprawdzaj plan zapytania przed i po optymalizacji. Szukaj Seq Scan na dużych tabelach — często sygnalizuje brak indeksu.\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>VACUUM i ANALYZE regularnie\u003C/strong>: Autovacuum zwykle wystarcza, ale dla tabel z dużą liczbą UPDATE/DELETE czasem warto uruchomić ręcznie.\u003C/p>\n\u003C/li>\n\u003C/ol>\n\u003Cp>\u003Cstrong>Redis — kluczowe wnioski:\u003C/strong>\u003C/p>\n\u003Col>\n\u003Cli>\n\u003Cp>\u003Cstrong>Cache tylko gorące dane\u003C/strong>: Nie wszystko musi być w cache. Cachuj często czytane dane, które są kosztowne do wygenerowania.\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Dobierz TTL do charakteru danych\u003C/strong>: Sesje użytkowników mogą żyć 24h, ceny produktów tylko 10 minut. Analizuj swoje access patterns.\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Cache invalidation wymaga strategii\u003C/strong>: Write-through dla krytycznych danych, lazy loading dla reszty. Unikaj cache stampede używając lock pattern.\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Używaj odpowiednich struktur danych\u003C/strong>: Hashes dla obiektów, Sets dla relacji, Sorted Sets dla rankingów. Każda struktura jest zoptymalizowana pod inny use case.\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Monitoruj hit ratio\u003C/strong>: Dobry cache to 80-90%+ hit ratio. Jeśli masz mniej, albo źle dobierasz co cachować, albo TTL jest za krótki.\u003C/p>\n\u003C/li>\n\u003C/ol>\n\u003Cp>Optymalizacja to proces iteracyjny. Zacznij od pomiarów \u003Cem>(EXPLAIN ANALYZE, monitoring Redis)\u003C/em>, zidentyfikuj bottleneck, zastosuj odpowiednią technikę, zmierz ponownie. Czasem indeks wystarczy, czasem potrzebujesz partycjonowania, a czasem Redis rozwiąże problem w sekundę.\u003C/p>\n\u003Cp>Najważniejsze: nie optymalizuj na ślepo. Zawsze mierz, zanim i po zmianach. To jedyny sposób, by wiedzieć, czy Twoja optymalizacja naprawdę pomogła.\u003C/p>\n",{"en":26,"pl":118},[27,30,34,37,40,44,48,52,56,59,62,65,68,71,74,77,80,83,86,89,92,95,98,101,104,108,112,115],{"id":28,"title":29,"mainLevel":20,"subLevel":14},"database-optimization-in-production-postgresql-and-redis","Database Optimization in Production: PostgreSQL and Redis",{"id":31,"title":32,"mainLevel":33,"subLevel":14},"indexes-in-postgresql-when-and-how-to-use-them","Indexes in PostgreSQL — when and how to use them",2,{"id":35,"title":36,"mainLevel":33,"subLevel":20},"b-tree-the-basic-index-for-every-occasion","B-Tree — the basic index for every occasion",{"id":38,"title":39,"mainLevel":33,"subLevel":33},"multi-column-indexes-order-matters","Multi-column indexes — order matters",{"id":41,"title":42,"mainLevel":33,"subLevel":43},"partial-indexes-smaller-and-faster","Partial indexes — smaller and faster",3,{"id":45,"title":46,"mainLevel":33,"subLevel":47},"gin-index-for-jsonb-and-full-text-search","GIN — index for JSONB and full-text search",4,{"id":49,"title":50,"mainLevel":33,"subLevel":51},"brin-efficient-index-for-huge-tables","BRIN — efficient index for huge tables",5,{"id":53,"title":54,"mainLevel":33,"subLevel":55},"when-not-to-create-indexes","When NOT to create indexes?",6,{"id":57,"title":58,"mainLevel":43,"subLevel":14},"table-partitioning-managing-huge-datasets","Table Partitioning — managing huge datasets",{"id":60,"title":61,"mainLevel":43,"subLevel":20},"when-is-it-worth-partitioning","When is it worth partitioning?",{"id":63,"title":64,"mainLevel":43,"subLevel":33},"range-partitioning-the-most-popular-choice","Range Partitioning — the most popular choice",{"id":66,"title":67,"mainLevel":43,"subLevel":43},"automating-partition-creation","Automating Partition Creation",{"id":69,"title":70,"mainLevel":43,"subLevel":47},"deleting-old-data-instantly","Deleting old data — instantly",{"id":72,"title":73,"mainLevel":43,"subLevel":51},"list-partitioning-for-categories","List Partitioning — for categories",{"id":75,"title":76,"mainLevel":43,"subLevel":55},"hash-partitioning-even-data-distribution","Hash Partitioning — even data distribution",{"id":78,"title":79,"mainLevel":47,"subLevel":14},"explain-analyze-your-best-friend","EXPLAIN ANALYZE — Your best friend",{"id":81,"title":82,"mainLevel":51,"subLevel":14},"vacuum-and-analyze-maintaining-database-health","VACUUM and ANALYZE — maintaining database health",{"id":84,"title":85,"mainLevel":55,"subLevel":14},"redis-in-memory-cache-for-hot-data","Redis — in-memory cache for hot data",{"id":87,"title":88,"mainLevel":55,"subLevel":20},"how-redis-works-and-why-its-so-fast","How Redis works and why it's so fast?",{"id":90,"title":91,"mainLevel":55,"subLevel":33},"cache-aside-pattern-the-most-popular-strategy","Cache-Aside Pattern — the most popular strategy",{"id":93,"title":94,"mainLevel":55,"subLevel":43},"ttl-time-to-live-how-long-should-data-live-in-cache","TTL (Time To Live) — how long should data live in cache?",{"id":96,"title":97,"mainLevel":55,"subLevel":47},"cache-invalidation-the-hardest-problem","Cache Invalidation — the hardest problem",{"id":99,"title":100,"mainLevel":55,"subLevel":51},"cache-stampede-the-problem-of-cascading-queries","Cache Stampede — the problem of cascading queries",{"id":102,"title":103,"mainLevel":55,"subLevel":55},"redis-hashes-memory-optimization","Redis Hashes — memory optimization",{"id":105,"title":106,"mainLevel":55,"subLevel":107},"redis-sets-caching-lists-and-relationships","Redis Sets — caching lists and relationships",7,{"id":109,"title":110,"mainLevel":55,"subLevel":111},"sorted-sets-rankings-and-leaderboards","Sorted Sets — rankings and leaderboards",8,{"id":113,"title":114,"mainLevel":107,"subLevel":14},"monitoring-redis-performance","Monitoring Redis Performance",{"id":116,"title":117,"mainLevel":111,"subLevel":14},"summary-from-theory-to-practice","Summary — from theory to practice",[119,122,125,128,131,134,137,140,143,146,149,152,155,158,161,164,167,170,173,176,179,182,185,188,191,194,197,200],{"id":120,"title":121,"mainLevel":20,"subLevel":14},"optymalizacja-baz-danych-w-produkcji-postgresql-i-redis","Optymalizacja baz danych w produkcji: PostgreSQL i Redis",{"id":123,"title":124,"mainLevel":33,"subLevel":14},"indeksy-w-postgresql-kiedy-i-jak-ich-uzywac","Indeksy w PostgreSQL — kiedy i jak ich używać",{"id":126,"title":127,"mainLevel":33,"subLevel":20},"b-tree-podstawowy-indeks-na-kazda-okazje","B-Tree — podstawowy indeks na każdą okazję",{"id":129,"title":130,"mainLevel":33,"subLevel":33},"indeksy-wielokolumnowe-porzadek-ma-znaczenie","Indeksy wielokolumnowe — porządek ma znaczenie",{"id":132,"title":133,"mainLevel":33,"subLevel":43},"indeksy-czesciowe-mniejsze-i-szybsze","Indeksy częściowe — mniejsze i szybsze",{"id":135,"title":136,"mainLevel":33,"subLevel":47},"gin-indeks-dla-jsonb-i-penotekstowego-wyszukiwania","GIN — indeks dla JSONB i pełnotekstowego wyszukiwania",{"id":138,"title":139,"mainLevel":33,"subLevel":51},"brin-oszczedny-indeks-dla-ogromnych-tabel","BRIN — oszczędny indeks dla ogromnych tabel",{"id":141,"title":142,"mainLevel":33,"subLevel":55},"kiedy-nie-tworzyc-indeksow","Kiedy NIE tworzyć indeksów?",{"id":144,"title":145,"mainLevel":43,"subLevel":14},"partycjonowanie-tabel-zarzadzanie-ogromnymi-zbiorami-danych","Partycjonowanie tabel — zarządzanie ogromnymi zbiorami danych",{"id":147,"title":148,"mainLevel":43,"subLevel":20},"kiedy-warto-partycjonowac","Kiedy warto partycjonować?",{"id":150,"title":151,"mainLevel":43,"subLevel":33},"partycjonowanie-zakresowe-range-najpopularniejszy-wybor","Partycjonowanie zakresowe (RANGE) — najpopularniejszy wybór",{"id":153,"title":154,"mainLevel":43,"subLevel":43},"automatyczne-tworzenie-partycji","Automatyczne tworzenie partycji",{"id":156,"title":157,"mainLevel":43,"subLevel":47},"usuwanie-starych-danych-byskawicznie","Usuwanie starych danych — błyskawicznie",{"id":159,"title":160,"mainLevel":43,"subLevel":51},"partycjonowanie-listowe-list-dla-kategorii","Partycjonowanie listowe (LIST) — dla kategorii",{"id":162,"title":163,"mainLevel":43,"subLevel":55},"partycjonowanie-hashowe-hash-rownomierne-rozozenie-danych","Partycjonowanie hashowe (HASH) — równomierne rozłożenie danych",{"id":165,"title":166,"mainLevel":47,"subLevel":14},"explain-analyze-twoj-najlepszy-przyjaciel","EXPLAIN ANALYZE — Twój najlepszy przyjaciel",{"id":168,"title":169,"mainLevel":51,"subLevel":14},"vacuum-i-analyze-utrzymanie-zdrowia-bazy","VACUUM i ANALYZE — utrzymanie zdrowia bazy",{"id":171,"title":172,"mainLevel":55,"subLevel":14},"redis-in-memory-cache-dla-goracych-danych","Redis — in-memory cache dla gorących danych",{"id":174,"title":175,"mainLevel":55,"subLevel":20},"jak-dziaa-redis-i-dlaczego-jest-tak-szybki","Jak działa Redis i dlaczego jest tak szybki?",{"id":177,"title":178,"mainLevel":55,"subLevel":33},"cache-aside-pattern-najpopularniejsza-strategia","Cache-Aside Pattern — najpopularniejsza strategia",{"id":180,"title":181,"mainLevel":55,"subLevel":43},"ttl-time-to-live-ile-dane-powinny-zyc-w-cache","TTL (Time To Live) — ile dane powinny żyć w cache?",{"id":183,"title":184,"mainLevel":55,"subLevel":47},"uniewaznianie-cache-najtrudniejszy-problem","Unieważnianie cache — najtrudniejszy problem",{"id":186,"title":187,"mainLevel":55,"subLevel":51},"cache-stampede-problem-lawinowego-odpytywania","Cache Stampede — problem lawinowego odpytywania",{"id":189,"title":190,"mainLevel":55,"subLevel":55},"redis-hashes-optymalizacja-pamieci","Redis Hashes — optymalizacja pamięci",{"id":192,"title":193,"mainLevel":55,"subLevel":107},"redis-sets-cachowanie-list-i-relacji","Redis Sets — cachowanie list i relacji",{"id":195,"title":196,"mainLevel":55,"subLevel":111},"sorted-sets-rankingi-i-leaderboards","Sorted Sets — rankingi i leaderboards",{"id":198,"title":199,"mainLevel":107,"subLevel":14},"monitorowanie-wydajnosci-redis","Monitorowanie wydajności Redis",{"id":201,"title":202,"mainLevel":111,"subLevel":14},"podsumowanie-od-teorii-do-praktyki","Podsumowanie — od teorii do praktyki",1781735646106]