Qismiy indekslar
Ushbu qo'llanmada PostgreSQLda jadvalning butun qatorlarini emas, balki faqat ko'rsatilgan shartga mos keladigan qismini indekslash uchun qismiy indekslar (Partial Indexes) dan qanday foydalanishni o'rganasiz.
Odatda indeks yaratilganda, PostgreSQL jadvaldagi har bir qator uchun indeks yozuvini tuzadi.
Biroq, ko'pincha siz faqat ma'lum bir qatorlar guruhi bo'yicha qidiruv qilasiz. Masalan:
WHERE is_active = true).WHERE discontinued = false).WHERE status = 'unpaid').Bunday hollarda butun jadvalni indekslash disk xotirasini isrof qiladi va har bir INSERT/UPDATE paytida indeksni yangilash sekinlashadi.
PostgreSQL WHERE bandi bilan faqat kerakli qatorlar uchun indeks tuzish imkonini beradi. Bu qismiy indeks (Partial Index) deb ataladi.
Qismiy indeksning sintaksisi:
CREATE INDEX [index_name]
ON table_name (column1, column2, ...)
WHERE condition;
Avval mahsulotlar jadvalini yaratamiz:
DROP TABLE IF EXISTS products CASCADE;
CREATE TABLE products (
id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
name VARCHAR(255) NOT NULL,
price DEC(10, 2) NOT NULL,
discontinued BOOL DEFAULT FALSE
);
Jadvalga 1000 ta mahsulot kiritamiz (ulardan 20% i sotuvdan chiqarilgan — discontinued = TRUE, 80% i esa faol sotuvda — discontinued = FALSE):
CREATE OR REPLACE FUNCTION insert_products (n INT)
RETURNS VOID
AS
$$
DECLARE
i INT;
BEGIN
FOR i IN 1..n LOOP
INSERT INTO products (name, price, discontinued)
VALUES (
'Product_' || i,
ROUND((RANDOM() * 100 + 1)::numeric, 2),
CASE WHEN RANDOM() < 0.2 THEN TRUE ELSE FALSE END
);
END LOOP;
END;
$$
LANGUAGE plpgsql;
SELECT insert_products(1000);
Biz faqat sotuvda faol bo'lgan (discontinued = FALSE) mahsulotlarning narxiga qismiy indeks quramiz:
CREATE INDEX idx_products_active_price
ON products (price)
WHERE discontinued = FALSE;
Endi faol mahsulotlar orasidan arzonlarini qidiramiz:
EXPLAIN SELECT
name,
price
FROM
products
WHERE
discontinued = FALSE
AND price < 50;
Natija:
QUERY PLAN
--------------------------------------------------------------------------------------------
Bitmap Heap Scan on products (cost=4.85..14.50 rows=150 width=21)
Recheck Cond: ((price < '50'::numeric) AND (NOT discontinued))
-> Bitmap Index Scan on idx_products_active_price (cost=0.00..4.81 rows=150 width=0)
Index Cond: (price < '50'::numeric)
PostgreSQL so'rovdagi discontinued = FALSE sharti indeksning WHERE shartiga mos kelganini ko'rib, ixcham idx_products_active_price indeksidan foydalandi.
Agar endi sotuvdan chiqarilgan tovarlarni qidirsak:
EXPLAIN SELECT
name,
price
FROM
products
WHERE
discontinued = TRUE
AND price < 50;
Natija:
QUERY PLAN
------------------------------------------------------------
Seq Scan on products (cost=0.00..18.50 rows=40 width=21)
Filter: (discontinued AND (price < '50'::numeric))
Indeksda faqat discontinued = FALSE qatorlari mavjud bo'lgani sababli, ushbu so'rov uchun PostgreSQL odatiy Seq Scan (jadvalni to'liq o'qish) ni amalga oshiradi.
status = 'active').CREATE UNIQUE INDEX ON users (email) WHERE is_deleted = FALSE; (o'chirilgan foydalanuvchilar bir xil emailga ega bo'lishi mumkin, ammo faollari emas).Partial Index) WHERE bandi orqali faqat ma'lum qatorlarni indekslaydi.