დაიწყეთ გამოკითხვის გეგმით, შემდეგ გამოასწორეთ ყველაზე დიდი খরচი. გამოიყენეთ / იმისათვის, რომ ნახოთ რა აკეთებს რეალურად მონაცემთა ბაზა, დაამატეთ სწორი , აღმოფხვრეთ მოთხოვნები და აირჩიეთ მხოლოდ საჭირო ডანა.
დაიწყეთ გამოკითხვის გეგმით, შემდეგ გამოასწორეთ ყველაზე დიდი খরচი. გამოიყენეთ / იმისათვის, რომ ნახოთ რა აკეთებს რეალურად მონაცემთა ბაზა, დაამატეთ სწორი , აღმოფხვრეთ მოთხოვნები და აირჩიეთ მხოლოდ საჭირო ডანა.
EXPLAINEXPLAIN ANALYZEEXPLAIN ANALYZE აჩვენებს შესრულების გეგმას და რეალურ დროებს. Seq Scan დიდი ცხრილის ზე არის კლასიკური წითელი ალერტი:
EXPLAIN ANALYZE
SELECT * FROM orders WHERE customer_id = 42;
-- Seq Scan on orders (cost=0.00..18500 rows=120)
-- Filter: (customer_id = 42)
-- rows removed by filter: 999880 ← scanned the whole table!
ინდექსი სრულ სკანირებას გადაქცევს სწრაფ ძებნაში:
CREATE INDEX idx_orders_customer ON orders (customer_id);
-- Now: Index Scan using idx_orders_customer (cost=0.42..8.5 rows=120)
-- 1,000,000-row scan → ~120-row lookup
ინდექსებს აქვთ ღირებულება წერაში: ყველა INSERT/UPDATE ასევე უნდა განაახლოს ინდექსი, ამიტომ ინდექსირეთ სვეტები, რომელზეც ფილტრავთ/შედიხართ/დალაგებთ — არა თითოეული სვეტი. კომპოზიტული ინდექსი (customer_id, created_at) ემსახურება WHERE customer_id = ? ORDER BY created_at ერთ სტრუქტურაში.
N+1 პრობლემა — ერთი მოთხოვნა სიის ზე, შემდეგ ერთი ყოველ რიგზე — არის ნელობის წამყვანი მიზეზი. შეცვალეთ ის eager loading-ით, JOIN-ით, ან ბაჩ IN (...)-ით:
-- N+1: 1 + 100 queries
SELECT * FROM orders; -- then per order: SELECT * FROM users WHERE id = ?
-- Fixed: one JOIN, only needed columns
SELECT o.id, o.total, u.name
FROM orders o JOIN users u ON u.id = o.user_id;
ასევე აირჩიეთ მხოლოდ საჭირო სვეტები (თავიდან აიცილეთ SELECT *) და გაუვრცელდით LIMIT/keyset pagination-ით, რათა არასოდეს ჩამოტვირთოთ მილიონი რიგი.
მონაცემთა ბაზა ყველაზე გავრცელებული სერვერის ღრძელბარი. გამოკითხვის გეგმის კითხვა გიჩვენებთ რატომ აკ ნელი მოთხოვნა დაშვების ნაცვლად; სწორი ინდექსი, N+1-ის ამოღება და შედეგის ნაკრების შემცირება ჩვეულებრივ გარდაქმნის წამების მოთხოვნებს მილიწამის მოთხოვნებში — ფიზიკური აღჭურვილობის გაფართოების გარეშე.